Konsep Dasar Log4j
30 Jul 2012Walaupun sudah dibuatkan minibook, tapi ternyata ada juga beberapa orang yang tidak paham bagaimana cara enable/disable log message di aplikasi Java. Oleh karena itu, baiklah saya jelaskan lagi secara lebih singkat.
life, learn, contribute
Software Developer berdomisili di Jabodetabek, berkutat di lingkungan open source, terutama Java dan Linux.
Walaupun sudah dibuatkan minibook, tapi ternyata ada juga beberapa orang yang tidak paham bagaimana cara enable/disable log message di aplikasi Java. Oleh karena itu, baiklah saya jelaskan lagi secara lebih singkat.
Setelah aplikasi kita selesai dibuat, langkah selanjutnya tentu saja adalah menjalankannya di server production. Dalam software development, ini disebut dengan transisi dari development menjadi operation.
Salah satu aspek penting dalam fase operation adalah monitoring performance. Monitoring dilakukan untuk berbagai tujuan, diantaranya :
Mengetahui karakteristik aplikasi dalam menggunakan resource. Informasi ini bisa kita gunakan untuk melakukan tuning performance
Mengetahui karakteristik user dalam menggunakan aplikasi. Perilaku user ini berguna untuk menentukan waktu-waktu sibuk dan waktu-waktu idle, sehingga kita bisa melakukan capacity planning dengan akurat.
Mengetahui berapa persen resource yang sudah terpakai, sehingga kita punya gambaran kapan harus melakukan upgrade, dan apa yang harus diupgrade
Mendapatkan notifikasi secepat mungkin pada saat sistem mengalami gangguan
Seberapa penting file di komputer kita? Tentu tidak ternilai harganya. Tapi apakah kita melakukan backup secara terhadap file-file di komputer kita? Beberapa menit yang lalu, saya menjawab tidak untuk pertanyaan tersebut.
Kenapa backup tidak dilakukan? Penyebab utamanya biasanya adalah karena merepotkan. Kita harus pilih file yang mau dibackup, membuka aplikasi backup, lalu menjalankannya. Walaupun cuma butuh waktu beberapa menit, tapi biasanya kita sering menunda dan akhirnya lupa.
Cara paling efektif untuk melakukan backup rutin adalah dengan mengotomasinya. Effort untuk melakukan setup cukup sekali saja, selanjutnya backup akan berjalan otomatis tanpa kita sadari. Pada artikel ini, saya akan posting teknik backup yang saya gunakan.
Sebelum kita mulai, terlebih dulu kita tentukan requirementnya, supaya jelas apa yang kita ingin capai. Saya ingin membackup folder tertentu di komputer saya (misalnya /home/endy dan /opt/multimedia/Photos). Backup ini dilakukan secara rutin (misalnya satu jam sekali, satu hari sekali, atau satu minggu sekali). Selain rutin, juga harus incremental. Artinya kalau saya punya backup hari ini jam 11, maka backup selanjutnya di jam 12 hanya menyimpan file yang berubah saja. Dengan demikian, saya bisa jalankan backupnya satu jam sekali dan tidak akan menyebabkan harddisk menjadi penuh dalam beberapa jam saja.
Staged Deployment
Pada waktu kita coding, tentunya kita melakukan test terhadap kode program yang kita tulis. Kita jalankan langkah-langkah sesuai yang telah didefinisikan dalam test scenario. Setelah test di komputer kita sendiri (local) selesai dilakukan, tentunya kode program tersebut tidak langsung kita deploy ke production. Best practicesnya adalah, kita deploy aplikasinya ke server testing untuk kemudian ditest oleh Software Tester. Barulah setelah dinyatakan OK oleh tester, aplikasi versi terbaru tersebut kita deploy ke production.
Dengan demikian, kita memiliki tiga deployment environment, yaitu :
development (komputer si programmer)
testing (test server)
production (live system)
Environment ini bisa lebih banyak lagi kalau aplikasi kita harus dites kompatibilitasnya dengan berbagai hardware atau sistem operasi.
Cara kerja seperti ini disebut dengan istilah staged deployment atau deployment bertahap. Dengan menggunakan staged deployment, kita mencegah terjadinya bug fatal di production/live system.
Tantangan yang kita hadapi adalah, bagaimana cara mengelola konfigurasi aplikasi kita sehingga bisa dideploy di berbagai environment secara baik. Teknik bagaimana cara melakukan ini berbeda-beda, tergantung bahasa pemrograman, framework, dan library yang kita gunakan.
Pada artikel ini, kita akan membahas cara mengelola konfigurasi deployment menggunakan teknologi yang biasa digunakan di ArtiVisi, yaituSpring Framework dan Logback.
Manajemen konfigurasi ini bisa kita lakukan dengan dua pendekatan, yaitu dikelola dengan Maven Profile, atau dengan konfigurasi Spring Framework.
Jika kita menggunakan Maven Profile, kita menambahkan opsi pada saat melakukan build, kira-kira seperti ini :
mvn -P production clean install
atau
mvn -Denv=production clean install
Dalam konfigurasi profile, kita bisa memilih file mana yang akan diinclude di dalam hasil build. Hasilnya, kita bisa menghasilkan artifact yang berbeda tergantung dari opsi yang kita berikan pada saat build.
Walaupun demikian, berdasarkan hasil Googling, ternyata metode ini tidak direkomendasikan. Justru konfigurasi melalui Spring lebih disarankan.
Dengan menggunakan konfigurasi Spring, artifact yang dihasilkan oleh build hanya satu jenis saja. Artifact ini berisi semua pilihan konfigurasi. Konfigurasi mana yang akan aktif pada saat dijalankan (runtime) akan ditentukan oleh setting environment variable, bukan oleh artifactnya.
Selanjutnya, kita akan membahas metode manajemen konfigurasi menggunakan Spring.
Konfigurasi yang biasanya berbeda adalah informasi koneksi database. Untuk membedakan masing-masing environment, kita akan membuat tiga file, yaitu:
jdbc.properties : digunakan di laptop programmer
jdbc.testing.properties : digunakan di server test
jdbc.production.properties : digunakan di live
Berikut contoh isi jdbc.properties, yaitu konfigurasi koneksi database di laptop saya :
hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost/kasbon?zeroDateTimeBehavior=convertToNull
jdbc.username = kasbon
jdbc.password = kasbon
Kemudian, ini file jdbc.testing.properties :
hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost/kasbon_testing?zeroDateTimeBehavior=convertToNull
jdbc.username = root
jdbc.password = admin
Perhatikan bahwa informasi nama database, username, dan password databasenya berbeda dengan yang ada di konfigurasi laptop.
Terakhir, jdbc.production.properties
hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost/kasbon_live?zeroDateTimeBehavior=convertToNull
jdbc.username = root
jdbc.password = admin
Ketiga file konfigurasi ini akan dibaca oleh konfigurasi Spring, yaitu di file applicationContext.xml. Isi lengkap dari file ini adalah sebagai berikut.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:property-placeholder location="
classpath*:jdbc.properties,
classpath*:jdbc.${stage}.properties
" />
<tx:annotation-driven />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.driver}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}" p:maxWait="40000"
p:maxActive="80" p:maxIdle="20" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource" p:configLocations="classpath*:com/artivisi/**/hibernate.cfg.xml">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
</beans>
Untuk lebih spesifik, konfigurasinya ada di baris berikut
<context:property-placeholder location="
classpath*:jdbc.properties,
classpath*:jdbc.${stage}.properties
" />
Di sana kita melihat ada variabel ${stage}. Variabel ${stage} ini akan dicari dari beberapa tempat, diantaranya environment variabel yang bisa diset di JVM ataupun di sistem operasi. Cara mengeset variabel ${stage} akan kita bahas sebentar lagi.
Di situ kita menyuruh Spring untuk membaca file jdbc.properties dan jdbc.${stage}.properties. Jika ada nilai variabel yang sama (misalnya jdbc.username), maka nilai variabel di file yang disebutkan belakangan akan menimpa nilai yang didefinisikan file di atasnya.
Contohnya, misalnya variabel ${stage} nilainya adalah testing. Maka Spring akan membaca file jdbc.properties dan jdbc.testing.properties. Karena kedua file memiliki variabel jdbc.url, maka isi jdbc.url di file jdbc.testing.properties akan menimpa nilai jdbc.url di jdbc.properties.
Bila variabel ${stage} tidak ada isinya, Spring akan mencari file yang namanya jdbc.${stage}.properties, dan tidak akan ketemu. Dengan demikian, nilai yang digunakan adalah yang ada di jdbc.properties.
Dengan demikian, behavior aplikasi adalah sebagai berikut
Bila variabel stage diset production atau testing, maka yang digunakan adalah nilai konfigurasi di jdbc.production.properties atau jdbc.testing.properties. Bila tidak diset atau diset selain itu, maka yang digunakan adalah konfigurasi di jdbc.properties
Behavior seperti inilah yang kita inginkan. Selanjutnya, tinggal kita isi nilai variabel stage.
Variabel stage bisa diset dengan berbagai cara. Bila kita menggunakan Apache Tomcat, maka kita mengedit file startup.sh atau startup.bat. Modifikasi baris yang berisi CATALINA_OPTS menjadi seperti ini :
export CATALINA_OPTS="-Dstage=production"
Atau, kita bisa jalankan dengan Jetty melalui Maven
mvn jetty:run -Dstage=testing
Bisa juga melalui environment variabel sistem operasi, di Linux kita set seperti ini.
EXPORT stage=production
Dengan menggunakan Spring seperti di atas, kita bisa membaca konfigurasi apa saja, misalnya
Konfigurasi email : bila aplikasi kita mengirim/menerima email
Konfigurasi server lain : bila aplikasi kita berinteraksi dengan aplikasi orang lain, misalnya webservice atau koneksi socket
dsb
Walaupun demikian, konfigurasi logger biasanya tidak diload oleh Spring, melainkan langsung dibaca oleh library loggernya.
Kita di ArtiVisi menggunakan SLF4J dan Logback. Cara konfigurasinya mirip dengan Spring. Kita punya satu master file yang akan membaca file lain sesuai isi variabel stage. Untuk itu kita siapkan beberapa file berikut:
logback.xml : file konfigurasi utama
logback.production.xml : konfigurasi logger production, akan diinclude oleh logback.xml
logback.testing.xml : konfigurasi logger testing, akan diinclude oleh logback.xml
logback.development.xml : konfigurasi logger development, akan diinclude oleh logback.xml
Berikut isi file logback.xml.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${catalina.home:-.}/logs/kasbon-${stage:-development}.log</file>
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<include resource="logback-${stage:-development}.xml"/>
</configuration>
Seperti kita lihat, file ini berisi konfigurasi yang berlaku umum, seperti appender yang digunakan. Di file ini kita menulis variabel seperti ini
${stage:-development}
Yang artinya adalah, isi dengan variabel stage, kalau variabel tersebut tidak diset, defaultnya adalah development. Ini sesuai dengan keinginan kita seperti pada waktu mengkonfigurasi Spring di atas.
Isi file logback-development.xml dan teman-temannya dapat dilihat di Github.
Demikianlah tutorial cara mengelola konfigurasi untuk keperluan staged deployment. Semoga bermanfaat.
Di milis manajemen proyek IT sedang rame diskusi tentang CMMI dan Scrum. Seperti layaknya diskusi yang rame, perdebatan dibumbui dengan segala macam mitos dan ‘FUDification’.
Berikut adalah tanggapan saya tentang mitos yang berkembang mengenai CMMI, dicopy-paste dari posting milis dengan sedikit penyesuaian.
Beberapa mitos yang akan diluruskan :
Pada artikel ini, kita akan meluruskan mitos-mitos tersebut.
CMMI bukanlah metodologi manajemen proyek seperti Scrum, IBM Rational Unified Process, XP, apalagi Waterfall.
CMMI sebetulnya sudah pernah saya jelaskan di posting saya sebelumnya. Tapi untuk lebih menyederhanakan lagi, kita bisa analogikan CMMI seperti akreditasi perguruan tinggi. Kalau kita mau daftar kuliah, biasanya kita cari tahu akreditasi kampus yang kita tuju. Semakin tinggi akreditasinya, semakin tinggi ekspektasi kita terhadap kualitas perguruan tinggi tersebut. Akreditasi perguruan tinggi ditentukan oleh banyak hal, diantaranya :
Untuk menentukan suatu kampus mendapat level A, B, atau lainnya, maka ada tim assessor yang akan memeriksa apakah kampus tersebut sudah memenuhi apa yang dipersyaratkan.
Demikian juga dengan CMMI, berisi seperangkat checklist yang bentuknya kira-kira seperti ini:
Level | Process Area | OK | Not OK |
---|---|---|---|
2 | REQM | v | |
2 | PP | v | |
2 | PMC | v | |
2 | MA | v |
Nah, checklist itu nanti akan dicentang sesuai dengan kapabilitas perusahaan yang diperiksa.
Adapun urusan Scrum, Waterfall, XP, whatever metodologi yang kita gunakan, hanyalah mencakup sebagian saja dari CMMI.
CMMI itu model untuk menggambarkan organisasi pembuat software yang mature. Apa itu mature? Salah satu karakteristiknya adalah konsistensi. Perusahaan yang gak mature, hasil kerjanya gak konsisten. Project A ontime, Project B molor 3 tahun. Project X bugnya dikit, Project Y isinya bug doang gak ada fiturnya.
Kalau kita bisa mengeksekusi project dengan sukses, kita hanya bisa lulus CMMI level 2. Untuk bisa mendapatkan level 3, kita harus bisa mengeksekusi project dengan sukses secara konsisten. Untuk bisa konsisten, maka kita harus bisa menduplikasi project sukses ke seluruh perusahaan. Jadi, kalau kita sudah sukses pakai Scrum di project kita sekarang, tetap saja baru level 2. Hanya setelah kesuksesan Scrum bisa direplikasi di keseluruhan perusahaan, barulah bisa level 3.
Seperti juga halnya replikasi resep McDonalds ke seluruh cabang, untuk bisa mereplikasi project sukses ke seluruh perusahaan, dibutuhkan kegiatan tambahan di level organisasi, misalnya :
Yang di dalam kurung adalah process area yang bersesuaian di CMMI.
Berurusan dengan perusahaan yang mature akan mengurangi resiko di client. Apa itu resiko?
Buat orang awam seperti kita, resiko adalah simply sekian persen kemungkinan adanya masalah di kemudian hari. Nah, ada perspektif finansial yang kita orang teknis biasanya gak kepikiran. Buat orang finance, persentase tersebut bisa diuangkan. Misalnya kita mau bikin aplikasi costnya 100 M, uangnya minjem ke bank. Karena pada dasarnya bank gak mau rugi, 100 M itu akan diasuransikan sama dia. Jadi kalo projectnya bubaran, kita gak sanggup bayar, hutangnya akan ditalangin sama asuransi.
Asuransi akan lihat, kita pakai vendor siapa. Kalo vendornya gak mature (baca: resiko tinggi) maka premi asuransinya akan tinggi. Akibatnya, biaya pinjaman kita (cost of money) juga tinggi.
Bisa aja kita bayar 100 M (pokok) + 20 M (bunga) + 20 M (asuransi). Padahal kalo vendornya mature, premi asuransinya cuma 5 M. Nah, jadi urusan resiko dan maturity ini bukan semata jargon2 aja, tapi ada duit beneran yang tersangkut di dalamnya.
Demikianlah mitos pertama, CMMI bukan metodologi manajemen proyek, melainkan manajemen keseluruhan perusahaan.
CMMI sama sekali tidak mengharuskan kita bikin dokumen apa-apa.
Yang ada, kita harus :
Berikut beberapa definisi singkat
Nah, kita harus membuktikan bahwa kita benar2 melakukan apa yang disuruh. Gimana cara membuktikannya?
Kita bisa :
Nah, dari 2 cara di atas, kalo kita benar-benar melakukan, akan lebih mudah menunjukkan yang #2. Tapi kalo akal2an, sebenarnya gak planning tapi mau ngakunya planning, akan lebih mudah memalsukan yang #1. Soalnya #2 gak bisa di-back-dated, sedangkan #1 bisa.
Jadi, fokusnya lebih ke melakukan proses, bukan membuat dokumen
Kemudian, ada kesalah-kaprahan juga yang umum terjadi tentang planning. Planning itu tidak sekali saja lalu dipakai sepanjang project. Project plan harus mencerminkan kondisi yang terbaru dari project. Misalnya, kita bikin plan awal (versi 1) selesai 3 bulan. Ternyata waktu monitoring di akhir bulan 1, kita udah tau bahwa gak bakalan selesai dalam 2 bulan sisanya. Kita harus melakukan controlling terhadap projectnya. Tindakan control bisa macam2, bisa kita tambah orang biar tetap selesai dalam 3 bulan, bisa juga revisi plannya sehingga mencerminkan kondisi setelah 1 bulan berjalan.
UUD 45 aja bisa diamandemen, masa project plan gak bisa :D
Contoh lain, mengelola requirement (Requirement Management), Level 2.
S.P 1.1 : Understand Requirement : kita harus memastikan bahwa requirement dipahami.
Gimana cara membuktikannya?
Kalo prosesnya benar-benar dijalankan, kita bisa tunjukkan email dari BA ke Client yang isinya mengkonfirmasi pemahaman BA tentang requirement yang diminta Client.
Atau kalo seperti Scrum, Clientnya hadir di ruangan yang sama, gak nyatet apa2, rekaman audio juga boleh. Intinya, ada sesuatu yang bisa ditunjukkan ke auditor bahwa kita sudah Understanding Requirement.
Kalo prosesnya palsu, artinya sebenarnya gak dilakukan, tapi mau lulus Level 2, maka dibuatlah dokumen palsu. Bentuknya biasanya review report, isinya item2 requirement, lalu nanti ada tandatangan client palsu.
So, overhead dokumen (mis: review report) itu ada kalo kita memalsukan proses.
Selama kita benar-benar menjalankan apa yang disuruh, pasti ada evidence bahwa kita menjalankan, entah itu bentuknya chat YM, email, Skype call, apalah terserah, tidak ada CMMI mewajibkan formatnya harus mp3 atau apa.
SP 1.2 : Obtain Commitment to Requirement : semua pihak harus commit terhadap requirement yang sudah dibuat.
Gimana cara membuktikan bahwa kita comply dengan SP ini?
Paling gampang, BA kirim email ke Client, “Pak, di iterasi ini, kita kerjakan req #12, #14, sama #15 ya. #13 pending dulu aja”
Client reply, “Ok”
That’s it, tunjukkan emailnya ke auditor, beres.
Kalau proses ini tidak dijalankan, akan menimbulkan masalah di kemudian hari. Usernya client bilang A, bosnya user bilang A+, programmer bilang C, PM bilang lain lagi. Sekali lagi, selama prosesnya dilakukan, emailnya pasti ada.
Kalo prosesnya palsu, atau clientnya gaptek gak kenal email, ya dibuatlah dokumen requirement sign off. Orang2 tandatangan. Dokumennya dijadikan evidence.
SP 1.3 : Manage Requirement Changes : kalo requirement berubah, harus di-manage.
Apa itu dimanage?
Dimanage artinya harus jelas :
Apa buktinya? Email boleh, chat log boleh, rekaman cctv boleh.
Ok, lalu kenapa semua harus ada evidence ??
Berikut joke dari auditor kita dulu,
In God We Trust, everybody else brings data.
Jadi, CMMI = banyak dokumen hanyalah mitos belaka. Untuk bisa melakukan verifikasi, auditor tentu butuh melihat evidence. Di jaman modern seperti sekarang, evidence bentuknya tidak harus dokumen tertulis yang dibuat dengan aplikasi office.