Membuat Program Visual C++ Yang Menulis Ke Windows Event Log


Sistem operasi Windows memiliki fasilitas logging yang disebut sebagai Windows Event Log. Pengguna dapat melihat log yang ada dengan memilih Control Panel, Administrative Tools, Event Viewer. Hampir semua aplikasi (terutama atau hanya aplikasi yang dibuat oleh Microsoft😉 ) mencatat aktifitasnya di sini. Dengan adanya mekanisme logging yang terpusat, seharusnya aplikasi tidak perlu menulis ke file tersendiri lagi dan pengguna juga cukup melihat semua catatan aplikasi di Event Viewer.

Pada sistem operasi Linux, logging ditangani oleh syslog. Untuk menulis ke syslog di sebuah program C di Linux, saya dapat memberikan perintah seperti:

#include <syslog.h>
...
openlog(identitas, LOG_NOWAIT, LOG_AUTH);
syslog(prioritas, "%s", pesan);
closelog();
...

Sangat sederhana bukan? Lalu bagaimana dengan Windows? Apa yang harus saya lakukan agar dapat menulis ke Windows Event Log? Pada Windows, logging sedikit lebih sulit karena logging merupakan bagian dari Event Tracing For Windows (ETW). Dengan demikian, aplikasi harus menyediakan provider yang bertugas mengirimkan event. Event Viewer (di Control Panel) dapat dianggap sebagai sebuah consumer yang membaca event dari aplikasi.

Saya akan mulai dengan membuat sebuah proyek Win32 Console Application di Visual Studio 2010. Pada saat membuat proyek, saya menghilangkan tanda centang pada Precompiled header. Saya meletakkan proyek ini pada lokasi C:\latihan\latihan_event_log.

Langkah awal dalam membuat aplikasi yang memakai ETW adalah membuat Instrumentation Manifest. Ini adalah sebuah file XML yang berisi informasi provider yang disediakan oleh aplikasi. Agar lebih mudah, saya akan menggunakan tool berbasis GUI yang disebut ECManGen.exe. Untuk itu, saya membuka Start Menu, memilih All Programs, Microsoft Visual Studio 2010, Visual Studio Tools, dan men-klik Visual Studio Command Prompt. Pada command prompt yang muncul, saya memberikan perintah berikut ini:

C:\> ECManGen.exe

Pada ECManGen, saya men-klik menu Edit, New, Provider untuk membuat sebuah provider baru. Saya kemudian mengisi informasi yang ada seperti yang terlihat pada gambar berikut ini:

Membuat provider baru

Membuat provider baru

Pada bagian decoding file locations, saya perlu memberikan lokasi file EXE dalam bentuk lokasi absolut. Sebagai contoh, saya mengisinya dengan C:\latihan\latihan_event_log\Debug\latihan_event_log.exe. Setelah selesai mengisi informasi yang ada, saya menyimpan perubahan dengan men-klik tombol Save yang ada di sisi kanan layar.

Langkah berikutnya adalah mendefinisikan sebuah channel dengan memilih menu Edit, New, Channel. Karena saya memilih untuk membuat sebuah channel baru, maka hasil log di Event Viewer akan muncul pada sebuah kategori tersendiri. Saya mengisi informasi channel seperti berikut ini:

Membuat channel baru

Membuat channel baru

Setelah itu, saya perlu mendefinisikan sebuah template dengan memilih menu Edit, New, Template. Sebuah template mewakili pesan atau data yang hendak dikirim ke Event Viewer. Saya mengisi informasi template seperti berikut ini:

Membuat template baru

Membuat template baru

Sebagai langkah terakhir, saya akan mendefinisikan sebuah event dengan memilih menu Edit, New, Event. Sebuah provider dapat menghasilkan lebih dari satu event. Pada latihan ini, saya hanya akan membuat sebuah event tunggal yang mewakili pesan kesalahan, seperti yang terlihat pada gambar berikut ini:

Membuat event baru

Membuat event baru

Saya kemudian menyimpan instrumentation manifest dengan memilih menu File, Save dan memilih C:\latihan\latihan_event_log\provider.man sebagai tujuan penyimpanan. Sesungguhnya sebuah instrumentation manifest adalah sebuah file XML sehingga saya dapat mengetik isinya sendiri bila tidak ingin memakai ECManGen.exe. Sebagai contoh, file provider.man yang dihasilkan oleh ECManGen.exe memiliki isi seperti berikut ini:

<?xml version="1.0" encoding="UTF-16"?>
<instrumentationManifest xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd" xmlns="http://schemas.microsoft.com/win/2004/08/events" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:trace="http://schemas.microsoft.com/win/2004/08/events/trace">
    <instrumentation>
        <events>
            <provider name="TheSolidSnake-Provider" guid="{2B1D473F-3A5B-49C5-8002-0F54E8FCF6BE}" symbol="THESOLIDSNAKE" resourceFileName="C:\latihan\latihan_event_log\Debug\latihan_event_log.exe" messageFileName="C:\latihan\latihan_event_log\Debug\latihan_event_log.exe">
                <events>
                    <event symbol="Kesalahan" value="1" version="1" channel="AplikasiTheSolidSnake" level="win:Error" template="Pesan" message="$(string.TheSolidSnake-Provider.event.1.message)">
                    </event>
                </events>
                <levels>
                </levels>
                <channels>
                    <channel name="AplikasiTheSolidSnake" chid="AplikasiTheSolidSnake" symbol="APLIKASI_THE_SOLID_SNAKE" type="Operational" enabled="true" message="$(string.TheSolidSnake-Provider.channel.APLIKASI_THE_SOLID_SNAKE.message)">
                    </channel>
                </channels>
                <templates>
                    <template tid="Pesan">
                        <data name="pesan" inType="win:UnicodeString" outType="xs:string">
                        </data>
                    </template>
                </templates>
            </provider>
        </events>
    </instrumentation>
    <localization>
        <resources culture="en-US">
            <stringTable>
                <string id="level.Error" value="Error">
                </string>
                <string id="TheSolidSnake-Provider.event.1.message" value="Terjadi Kesalahan: %s">
                </string>
                <string id="TheSolidSnake-Provider.channel.APLIKASI_THE_SOLID_SNAKE.message" value="Informasi mengenai aplikasi TheSolidSnake.">
                </string>
            </stringTable>
        </resources>
    </localization>
</instrumentationManifest>

Langkah berikutnya adalah memanggil Message Compiler (MC.exe) untuk menghasilkan kode program dan file resources berdasarkan isi provider.man. Untuk itu, saya memanggil MC.exe dengan perintah seperti berikut ini:

C:\latihan\latihan_event_log> MC.exe -um provider.man

Perintah di atas akan menghasilkan file berupa provider.h, provider.rc, providerTEMP.BIN, dan MSG00001.bin pada lokasi direktori proyek. Saya perlu menambahkan file ini agar dikenali oleh Visual Studio. Untuk menyertakan referensi ke provider.h, saya dapat men-klik kanan pada Header Files dan memilih menu Add, Existing Item. Pada dialog yang muncul, saya memilih file provider.h dan men-klik tombol Add. Saya juga melakukan hal yang sama pada Resource Files untuk menyertakan file provider.rc.

Saya kini dapat membuat men-install instrumentation manifest dengan menggunakan Wevtutil.exe. Tapi sebelumnya, saya perlu membuka Command Prompt sebagai Administrator terlebih dahulu sebelum mengetikkan perintah berikut ini:

C:\latihan\latihan_event_log> wevtutil.exe im provider.man
**** Warning: Publisher TheSolidSnake-Provider resources are not accessible.

Pesan peringatan yang muncul boleh diabaikan karena file executable memang belum dibuat. Hasil dari perintah tersebut adalah saya bisa menemukan channel baru di Event Viewer seperti yang terlihat pada gambar berikut ini:

Channel baru di Event Viewer

Channel baru di Event Viewer

Sekarang, saya siap untuk membuat kode program. Sebagai contoh, saya membuat kode program sederhana seperti berikut ini:

#include <Windows.h>
#include "stdafx.h"
#include "provider.h"

int _tmain(int argc, _TCHAR* argv[])
{
    ULONG status;
    status = EventRegisterTheSolidSnake_Provider();
    if (status == ERROR_SUCCESS) {
        wprintf(L"Berhasil melakukan registrasi provider.\n");
    }
    status = EventWriteKesalahan(L"Ini kesalahan latihan.");
    if (status == ERROR_SUCCESS) {
        wprintf(L"Berhasil mengirim event.\n");
    }
    status = EventUnregisterTheSolidSnake_Provider();
    if (status == ERROR_SUCCESS) {
        wprintf(L"Berhasil membatalkan registrasi provider.\n");
    }
    return 0;
}

Header provider.h yang dihasilkan oleh MC.exe mengandung macro seperti EventRegisterTheSolidSnake_Provider, EventWriteKesalahan dan EventUnregisterTheSolidSnake_Provider yang dapat saya pakai di kode program. Pada dasarnya macro yang ada merupakan versi singkat yang memanggil EventRegister(), EventUnregister(), dan EventWrite().

Setelah menjalankan aplikasi, saya dapat menemukan sebuah log baru di channel yang saya buat di Event Viewer seperti yang terlihat pada gambar berikut ini:

Log yang dihasilkan aplikasi

Log yang dihasilkan aplikasi

Bagaimana bila saya tidak ingin membuat sebuah channel baru? Misalnya, bagaimana bila saya ingin log muncul di bagian Application di Windows Log? Saya perlu mengubah definisi event menjadi seperti berikut ini:

Memakai channel yang sudah ada

Memakai channel yang sudah ada

Setelah menyimpan insrumentation manifest, saya perlu kembali memberikan perintah MC.exe untuk memperbaharui file resources. Bila saya menjalankan program, kali ini log akan tercatat di Windows Log, Application seperti yang terlihat pada gambar berikut ini:

Log dari aplikasi kini muncul di Windows Log

Log dari aplikasi kini muncul di Windows Log

Perihal Solid Snake
I'm nothing...

2 Responses to Membuat Program Visual C++ Yang Menulis Ke Windows Event Log

  1. Ping-balik: Membuat Plugin MySQL Yang Menulis Hasil Audit Ke Windows Event Log | The Solid Snake

  2. Ping-balik: Memakai Full-Text Search Di MySQL Server | Programming Logic And Technology

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: