Series MapLesson 04 / 62
Focus mode active/Press Alt+Shift+R to toggle/Esc to exit
Start HereOrdered learning track

Logging Foundation

Dasar log event, log line, structured log, JSON log, log level, timestamp, context field, dan stack trace untuk Java/JAX-RS production systems.

25 min read4809 words
PrevNext
Lesson 0462 lesson track01–12 Start Here
#logging#structured-logging#json-log#log-level+1 more

Cheatsheet Observability Part 004 — Logging Foundation

Tujuan Part Ini

Part ini membangun fondasi logging untuk sistem enterprise Java/JAX-RS. Fokusnya bukan langsung ke SLF4J, Logback, Log4j2, atau konfigurasi encoder. Fokusnya adalah memahami apa itu log yang baik, apa yang membuat log berguna saat incident, dan apa yang membuat log berbahaya, mahal, atau menyesatkan.

Setelah membaca part ini, Anda harus mampu memahami:

  • apa itu log
  • apa itu log event
  • apa itu log line
  • structured log vs plain text log
  • JSON log
  • log level
  • logger
  • appender/handler
  • log pattern
  • timestamp dan timezone
  • thread name
  • class/logger name
  • message
  • exception stack trace
  • context field
  • logging correctness, performance, privacy, cost, dan operational concern

Logging adalah signal observability paling dekat dengan code. Karena itu logging sering terlihat mudah. Justru karena mudah, logging sering menjadi sumber masalah production: noise, missing context, duplicate stack trace, PII leakage, expensive ingestion, misleading severity, dan log yang tidak bisa dikorelasikan.


Ringkasan Mental Model

Log adalah catatan event yang terjadi di sistem.

Namun dalam production system, definisi praktisnya lebih tajam:

Log adalah bukti operasional terstruktur yang membantu engineer memahami apa yang terjadi pada request, job, workflow, dependency call, state transition, atau security/business action tertentu.

Log bukan sekadar string. Log yang baik adalah event dengan context.

Contoh log buruk:

Failed to process order

Masalahnya:

  • order mana?
  • request mana?
  • tenant mana?
  • failure apa?
  • retryable atau tidak?
  • terjadi di layer mana?
  • dependency mana?
  • status order berubah atau tidak?
  • apakah ada customer impact?

Contoh log lebih baik:

{
  "timestamp": "2026-07-11T14:01:42.512Z",
  "level": "ERROR",
  "service": "order-service",
  "environment": "prod",
  "version": "2026.07.11-1842",
  "event": "order.submission.failed",
  "message": "Order submission failed due to downstream fulfillment timeout",
  "trace_id": "7f1d...",
  "span_id": "a93b...",
  "correlation_id": "corr-20260711-8891",
  "tenant_id": "tenant-123",
  "order_id": "O-91821",
  "request_id": "req-7731",
  "dependency": "fulfillment-service",
  "error_code": "FULFILLMENT_TIMEOUT",
  "retryable": true,
  "attempt": 3,
  "latency_ms": 5000,
  "exception_class": "java.net.SocketTimeoutException"
}

Log ini tidak sempurna untuk semua kasus, tetapi jauh lebih kuat karena bisa dicari, dikorelasikan, dan dipakai untuk incident reconstruction.


Apa Itu Log?

Log adalah output yang dihasilkan aplikasi atau platform untuk mencatat sesuatu yang terjadi.

Dalam sistem Java/JAX-RS, log bisa berasal dari:

  • application code
  • framework
  • Servlet container
  • JAX-RS runtime
  • dependency library
  • JDBC driver
  • connection pool
  • ORM/MyBatis
  • Kafka/RabbitMQ client
  • Redis client
  • workflow engine
  • Kubernetes/container runtime
  • NGINX/ingress/API gateway
  • cloud platform

Tidak semua log memiliki nilai yang sama. Ada log yang penting untuk debugging, ada yang hanya noise, ada yang berbahaya karena membocorkan data, dan ada yang mahal karena volume tinggi.

Log yang baik biasanya memenuhi syarat berikut:

  • menjelaskan event tertentu
  • punya timestamp akurat
  • punya severity yang benar
  • punya context teknis
  • punya context bisnis jika relevan
  • bisa dikorelasikan dengan request/trace/event lain
  • aman dari data sensitif
  • tidak terlalu verbose
  • tidak terlalu minim
  • stabil enough untuk query dan dashboard

Apa Itu Log Event?

Log event adalah satu kejadian yang dicatat.

Contoh log event:

  • request diterima
  • request selesai
  • validation gagal
  • dependency timeout
  • order state berubah
  • Kafka message dipublish
  • Kafka message gagal diproses
  • Redis cache miss
  • DB transaction rollback
  • user melakukan approval
  • security authorization gagal
  • background job dimulai
  • background job selesai

Log event harus menjawab:

Apa yang terjadi?
Kapan terjadi?
Di service mana?
Di environment mana?
Terkait request/job/event apa?
Terkait entity bisnis apa?
Apa hasilnya?
Jika gagal, gagal karena apa?

Event Name

Dalam structured logging, event name membantu membuat log lebih queryable.

Contoh:

quote.pricing.started
quote.pricing.completed
quote.pricing.failed
order.submission.started
order.submission.failed
kafka.message.publish.failed
redis.cache.miss
workflow.task.failed

Event name lebih stabil daripada message text.

Message text boleh berubah agar lebih manusiawi. Event name sebaiknya stabil agar query dan dashboard tidak mudah rusak.


Apa Itu Log Line?

Log line adalah representasi fisik dari log event dalam output log.

Dalam plain text log, satu event biasanya satu baris:

2026-07-11 14:01:42 ERROR order-service Order submission failed for order O-91821

Dalam JSON log, satu event juga idealnya satu baris JSON:

{"timestamp":"2026-07-11T14:01:42.512Z","level":"ERROR","service":"order-service","event":"order.submission.failed","order_id":"O-91821"}

Mengapa satu event satu line penting?

  • log collector biasanya membaca line-based stream
  • multi-line log bisa terpecah jika parser salah
  • stack trace perlu ditangani dengan encoder/collector yang benar
  • JSON log harus valid per line agar mudah diparse

Stack trace adalah pengecualian yang harus ditangani dengan benar oleh logging framework atau log collector.


Structured Log vs Plain Text Log

Plain Text Log

Plain text log mudah dibaca manusia, tetapi sulit diproses mesin.

Contoh:

Order submission failed for tenant tenant-123 order O-91821 due to timeout

Kelebihan:

  • cepat ditulis
  • mudah dibaca sekilas
  • cocok untuk local development sederhana

Kekurangan:

  • parsing rapuh
  • field tidak konsisten
  • query sulit
  • dashboard sulit
  • filtering by field sulit
  • correlation sering hilang

Structured Log

Structured log menyimpan event sebagai key-value fields.

Contoh:

{
  "event": "order.submission.failed",
  "tenant_id": "tenant-123",
  "order_id": "O-91821",
  "error_code": "FULFILLMENT_TIMEOUT",
  "retryable": true
}

Kelebihan:

  • mudah di-query
  • mudah di-index
  • mudah dikorelasikan
  • lebih stabil untuk dashboard/alert
  • field bisa distandarkan antar service

Kekurangan:

  • perlu schema discipline
  • bisa mahal jika terlalu banyak field
  • bisa membocorkan data jika field tidak direview
  • bisa menyebabkan index/storage overhead

Untuk enterprise production system, structured logging hampir selalu lebih cocok daripada plain text logging.


JSON Log

JSON log adalah bentuk structured log yang umum dipakai di container/cloud environment.

Contoh field standar:

{
  "timestamp": "2026-07-11T14:01:42.512Z",
  "level": "INFO",
  "service": "quote-service",
  "environment": "prod",
  "version": "2026.07.11-1842",
  "logger": "com.company.quote.PricingResource",
  "thread": "http-nio-8080-exec-12",
  "message": "Quote pricing completed",
  "event": "quote.pricing.completed",
  "trace_id": "4f8c...",
  "span_id": "9a2e...",
  "correlation_id": "corr-...",
  "tenant_id": "tenant-123",
  "quote_id": "Q-88421",
  "duration_ms": 348
}

JSON log harus dijaga agar:

  • valid JSON
  • satu event satu JSON object
  • field naming konsisten
  • timestamp format konsisten
  • numeric field disimpan sebagai number, bukan string jika memungkinkan
  • boolean field disimpan sebagai boolean
  • nested object digunakan dengan hati-hati
  • field sensitive tidak disimpan

Field Naming

Pilih convention dan konsisten.

Contoh snake_case:

trace_id
span_id
correlation_id
tenant_id
order_id
error_code
status_code
latency_ms

Contoh camelCase:

traceId
spanId
correlationId
tenantId
orderId
errorCode
statusCode
latencyMs

Yang paling penting bukan snake_case vs camelCase. Yang paling penting adalah konsistensi antar service dan backend query.


Log Level

Log level menunjukkan severity atau kepentingan event.

Level umum:

  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL, jika framework mendukung atau convention internal menggunakannya

Part khusus log level akan dibahas lebih dalam nanti. Di part ini, cukup pahami prinsip dasar:

LevelMakna DasarContoh
TRACEDetail sangat rendah untuk debugging sangat granularMasuk/keluar method internal tertentu
DEBUGDetail debugging yang biasanya tidak aktif di productionQuery decision, branch detail, intermediate state
INFOEvent operasional normal yang pentingRequest completed, job completed, state transition
WARNKondisi abnormal tetapi service masih bisa melanjutkanRetryable timeout, fallback used, validation anomaly
ERRORFailure yang menyebabkan operasi gagal atau butuh perhatianUnhandled exception, dependency failure, transaction rollback

Log level harus dipakai dengan disiplin.

Kesalahan umum:

  • validation error expected dicatat sebagai ERROR
  • retry success tetap meninggalkan ERROR yang membingungkan
  • dependency timeout dicatat tanpa context retry
  • semua event bisnis dicatat INFO tanpa kontrol volume
  • DEBUG aktif di production tanpa sampling
  • ERROR dicatat di banyak layer untuk exception yang sama

Logger

Logger adalah object atau abstraction yang dipakai code untuk menulis log.

Di Java, logger biasanya dibuat per class:

private static final Logger log = LoggerFactory.getLogger(PricingService.class);

Logger name biasanya mengikuti class/package name:

com.company.quote.pricing.PricingService

Logger name berguna untuk:

  • filter log berdasarkan package/class
  • mengubah log level runtime untuk area tertentu
  • mencari sumber log
  • mengurangi noise dari library tertentu

Namun logger name bukan pengganti event name.

Logger name menjawab:

Dari class/package mana log ini berasal?

Event name menjawab:

Kejadian domain/operasional apa yang dicatat?

Keduanya berguna.


Appender, Handler, and Sink

Appender atau handler adalah komponen yang mengirim log ke tujuan tertentu.

Tujuan umum:

  • console/stdout
  • file
  • rolling file
  • remote log collector
  • syslog
  • cloud logging backend
  • audit storage

Di container/Kubernetes, pola umum adalah:

Application -> stdout/stderr -> container runtime -> node agent -> log backend

Aplikasi biasanya tidak perlu menulis langsung ke file internal container kecuali ada alasan khusus.

Risiko Appender

Appender dapat menjadi bottleneck.

Risiko:

  • synchronous appender memperlambat request
  • remote appender blocking saat network issue
  • file appender memenuhi disk
  • async appender queue penuh dan drop log
  • log collector tidak membaca format multi-line dengan benar

Untuk production, logging pipeline harus dipahami sebagai bagian dari reliability path.


Log Pattern

Log pattern menentukan format output plain text atau field dasar.

Contoh pattern plain text:

%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %-5level [%thread] %logger{36} trace=%X{trace_id} corr=%X{correlation_id} - %msg%n%ex

Di structured logging, pattern sering digantikan oleh JSON encoder.

Pattern atau encoder harus memastikan field penting masuk:

  • timestamp
  • level
  • logger
  • thread
  • message
  • exception
  • MDC fields
  • service metadata

Kesalahan umum:

  • pattern tidak memasukkan MDC
  • timestamp tanpa timezone
  • exception stack trace tidak tercetak
  • message JSON dicampur dengan plain text sehingga parser gagal
  • field service/environment/version tidak ada

Timestamp

Timestamp adalah field kritikal.

Tanpa timestamp yang benar, incident timeline tidak bisa dipercaya.

Rekomendasi umum:

  • gunakan UTC untuk log production
  • gunakan ISO-8601/RFC3339 format
  • sertakan millisecond atau nanosecond precision jika backend mendukung
  • hindari local timezone ambigu
  • pastikan clock node/container sinkron

Contoh baik:

2026-07-11T14:01:42.512Z

Contoh kurang baik:

07/11/26 2:01 PM

Masalah timestamp umum:

  • timezone berbeda antar service
  • clock skew antar node
  • log ingestion time dipakai sebagai event time
  • timestamp aplikasi dan timestamp platform tidak sejajar
  • async event timestamp producer dan consumer tertukar

Saat incident, urutan event sering menjadi bukti utama. Timestamp salah dapat menyebabkan RCA salah.


Timezone

Untuk sistem enterprise multi-region, timezone adalah sumber kebingungan.

Prinsip:

  • log event time sebaiknya UTC
  • UI dashboard boleh menampilkan local timezone pengguna
  • audit report mungkin perlu timezone bisnis tertentu, tetapi raw audit timestamp tetap harus jelas
  • jangan mencampur timezone dalam field yang sama

Field yang bisa dipakai:

{
  "timestamp": "2026-07-11T14:01:42.512Z",
  "event_timezone": "UTC"
}

Biasanya Z sudah cukup menunjukkan UTC, tetapi beberapa organisasi tetap menambah field timezone untuk eksplisit.


Thread Name

Thread name membantu debugging concurrency dan execution context.

Contoh thread name:

http-nio-8080-exec-12
pool-4-thread-3
kafka-consumer-quote-events-1
scheduler-reconciliation-2
virtual-thread-102

Thread name berguna untuk:

  • membedakan HTTP request thread dan background job
  • melihat thread pool yang menjalankan task
  • debugging async context loss
  • debugging blocking/latency issue
  • menghubungkan log dengan thread dump

Namun thread name bukan correlation ID. Thread bisa digunakan ulang untuk request berbeda. Jangan mengandalkan thread name untuk mengikuti request.


Class Name and Logger Name

Class/logger name menjelaskan lokasi code yang menghasilkan log.

Contoh:

com.company.order.submission.OrderSubmissionService

Berguna untuk:

  • menemukan source code
  • filter log area tertentu
  • runtime log level adjustment
  • memahami layer aplikasi

Namun terlalu bergantung pada class name bisa membuat log brittle.

Jika class berubah karena refactor, query berbasis logger name bisa rusak. Untuk business/operational query, gunakan event name dan structured fields.


Message

Message adalah teks manusia yang menjelaskan event.

Message yang baik:

  • ringkas
  • jelas
  • tidak bergantung pada parsing
  • tidak menyimpan data sensitif
  • melengkapi structured fields
  • tidak menyembunyikan error code atau context penting

Contoh buruk:

Error happened

Contoh lebih baik:

Order submission failed due to downstream fulfillment timeout

Tetapi jangan menaruh semua context hanya di message.

Kurang baik:

Order O-91821 for tenant tenant-123 failed after 3 attempts with error FULFILLMENT_TIMEOUT and correlation corr-123

Lebih baik:

{
  "message": "Order submission failed due to downstream fulfillment timeout",
  "order_id": "O-91821",
  "tenant_id": "tenant-123",
  "attempt": 3,
  "error_code": "FULFILLMENT_TIMEOUT",
  "correlation_id": "corr-123"
}

Message untuk manusia. Fields untuk mesin.


Exception Stack Trace

Stack trace menunjukkan call stack saat exception terjadi.

Stack trace berguna untuk:

  • menemukan source line
  • memahami exception path
  • membedakan root cause dan wrapper exception
  • debugging unexpected error
  • menghubungkan error dengan code path

Namun stack trace juga bisa menjadi masalah:

  • volume besar
  • duplicate di banyak layer
  • mengandung data sensitif di message
  • sulit diparse jika multi-line tidak dikonfigurasi
  • sering noisy jika exception expected

Prinsip Exception Logging

  1. Log exception di boundary yang tepat.
  2. Jangan log exception yang sama sebagai ERROR di setiap layer.
  3. Untuk expected validation/domain error, jangan selalu pakai stack trace.
  4. Sertakan error code dan business context.
  5. Pastikan stack trace masuk field exception yang diparse backend.
  6. Jangan menelan exception tanpa log atau metric.

Contoh buruk:

try {
    submitOrder(command);
} catch (Exception e) {
    log.error("Failed");
}

Masalah:

  • stack trace hilang
  • context hilang
  • error type hilang

Contoh lebih baik:

try {
    submitOrder(command);
} catch (FulfillmentTimeoutException e) {
    log.warn("Order submission dependency timeout",
        kv("event", "order.submission.dependency_timeout"),
        kv("order_id", command.orderId()),
        kv("tenant_id", command.tenantId()),
        kv("dependency", "fulfillment-service"),
        kv("retryable", true),
        e);
    throw e;
}

Syntax kv(...) bergantung pada logging library/encoder yang digunakan. Prinsipnya: context harus menjadi field, bukan hanya message.


Context Field

Context field adalah field tambahan yang membuat log bisa dikorelasikan dan dipahami.

Field umum:

timestamp
level
service
environment
version
logger
thread
message
event
trace_id
span_id
correlation_id
request_id
tenant_id
actor_id
quote_id
order_id
http_method
http_route
http_status_code
latency_ms
error_code
exception_class

Context field harus dipilih berdasarkan event.

Tidak semua log perlu semua field. Tetapi log penting harus punya field yang cukup untuk diagnosis.

Context Teknis

  • service
  • environment
  • version
  • instance/pod
  • thread
  • logger
  • trace ID
  • span ID
  • request ID
  • route
  • status code
  • dependency

Context Bisnis

  • tenant ID
  • account/customer ID jika aman dan diperbolehkan
  • quote ID
  • order ID
  • process instance ID
  • workflow task ID
  • product/catalog ID jika relevan

Context Security

  • actor ID
  • auth method
  • permission/scope
  • source IP jika policy mengizinkan
  • impersonation/delegation indicator

Security context harus direview ketat agar tidak membocorkan data.


Logging Lifecycle di Java/JAX-RS Request

Contoh flow:

HTTP request
  -> ingress/access log
  -> JAX-RS request filter
  -> resource method
  -> service layer
  -> DB/Redis/downstream/messaging
  -> exception mapper if failed
  -> JAX-RS response filter
  -> response returned

Logging points yang umum:

Request Start

Dicatat di filter.

Field:

  • request ID
  • correlation ID
  • trace ID jika tersedia
  • method
  • route/path
  • tenant if resolved
  • actor if authenticated
  • client metadata yang aman

Hati-hati: request start log bisa volume tinggi. Beberapa organisasi hanya mencatat request end log.

Request End

Dicatat di response filter.

Field:

  • status code
  • latency
  • response size jika tersedia
  • route template
  • error code jika gagal
  • trace/correlation ID

Request end log biasanya lebih berguna untuk access-style application log.

Domain Operation

Dicatat di service layer saat aksi penting terjadi.

Contoh:

  • quote priced
  • order submitted
  • approval requested
  • fulfillment command created

Field:

  • business key
  • state before/after jika relevan
  • actor
  • tenant
  • correlation ID

Dependency Failure

Dicatat dekat boundary dependency.

Field:

  • dependency name
  • operation
  • latency
  • timeout
  • status/error
  • retry attempt
  • retryable

Exception Mapping

Dicatat di boundary error response.

Field:

  • exception class
  • error code
  • HTTP status
  • route
  • request ID
  • trace ID
  • business key if available

Logging untuk PostgreSQL/MyBatis/JPA/JDBC

Database logging harus hati-hati.

Yang sering dibutuhkan:

  • slow query indicator
  • transaction rollback
  • pool exhaustion
  • deadlock/lock wait
  • rows affected mismatch
  • optimistic lock conflict
  • migration failure

Yang berisiko:

  • SQL parameter sensitif
  • full query dengan customer data
  • excessive query logs di high-throughput path
  • log every query di production tanpa sampling

Contoh useful application log:

{
  "event": "order.repository.update_conflict",
  "level": "WARN",
  "order_id": "O-91821",
  "tenant_id": "tenant-123",
  "expected_version": 12,
  "actual_version": 13,
  "error_code": "OPTIMISTIC_LOCK_CONFLICT"
}

Ini lebih berguna daripada sekadar:

Update failed

Logging untuk Kafka/RabbitMQ

Messaging logging harus menjelaskan lifecycle message.

Useful event:

  • message received
  • message processed
  • message processing failed
  • message retried
  • message sent to DLQ
  • publish failed
  • ack/nack failure

Field penting:

  • topic/exchange/queue
  • consumer group
  • partition/offset jika Kafka
  • routing key jika RabbitMQ
  • message ID
  • event ID
  • correlation ID
  • causation ID
  • trace ID
  • event age
  • attempt
  • error code

Hindari log payload penuh. Payload bisa besar dan sensitif.


Logging untuk Redis

Redis logging biasanya tidak perlu mencatat setiap command di production. Gunakan logs untuk event penting atau failure.

Useful event:

  • Redis unavailable
  • command timeout
  • lock acquisition failed
  • idempotency conflict
  • cache serialization error
  • Redis stream processing failed

Field penting:

  • operation category
  • key category, bukan raw key jika sensitif
  • latency
  • timeout
  • error code
  • retryable

Contoh:

{
  "event": "redis.lock.acquire.failed",
  "level": "WARN",
  "lock_name": "order-submission",
  "order_id": "O-91821",
  "tenant_id": "tenant-123",
  "error_code": "LOCK_ALREADY_HELD"
}

Logging untuk Camunda/Workflow

Workflow logging harus membantu menjawab:

  • process stuck di mana?
  • task gagal karena apa?
  • message correlation gagal?
  • worker retry keberapa?
  • human task aging?

Field penting:

  • process definition key
  • process instance ID
  • business key
  • task ID
  • activity ID
  • incident ID
  • retry count
  • error code
  • correlation ID

Jangan log process variables penuh tanpa review. Variables bisa mengandung data sensitif dan payload besar.


Logging untuk NGINX, Ingress, and Edge

Edge logs berbeda dari application logs, tetapi harus bisa dikorelasikan.

Field penting:

  • request ID
  • traceparent if propagated
  • client IP policy
  • method
  • path
  • status
  • upstream status
  • request time
  • upstream response time
  • user agent
  • forwarded headers

Edge logs berguna untuk membedakan:

  • request tidak sampai aplikasi
  • upstream timeout
  • client disconnect
  • gateway/auth failure
  • service unavailable

Logging di Docker/Kubernetes

Di container, log biasanya keluar ke stdout/stderr.

Prinsip:

  • aplikasi menulis structured log ke stdout/stderr
  • container runtime menangkap log
  • node agent mengirim ke backend
  • labels/metadata Kubernetes memperkaya log

Kubernetes metadata yang berguna:

  • namespace
  • pod name
  • container name
  • node name
  • deployment
  • app label
  • version label
  • image digest

Masalah umum:

  • pod restart membuat log lokal hilang jika tidak dikirim
  • multi-line stack trace terpecah
  • stdout/stderr diperlakukan berbeda
  • log volume menyebabkan throttling/dropping
  • labels tidak konsisten

Logging di AWS/Azure/Hybrid

Cloud/on-prem/hybrid deployment menambah variasi pipeline.

Yang harus diperhatikan:

  • log ingestion delay
  • per-environment routing
  • cross-region query
  • access control
  • encryption
  • retention
  • cloud audit logs
  • managed service logs
  • network/load balancer logs

Untuk hybrid system, common fields menjadi sangat penting:

service
environment
region
cluster
namespace
version
trace_id
correlation_id

Tanpa common fields, korelasi cloud/on-prem sulit dilakukan.


Failure Mode Logging

1. Missing Log

Event penting tidak dicatat.

Dampak:

  • incident sulit direkonstruksi
  • root cause hanya dugaan
  • customer impact sulit dihitung

Contoh:

  • state transition order tidak dilog
  • DLQ publish tidak dilog
  • config change tidak diaudit

2. Missing Context

Log ada tetapi tidak punya ID penting.

Dampak:

  • tidak bisa mencari semua event untuk request/order tertentu
  • trace/log tidak bisa dikorelasikan

Contoh:

Failed to process message

Tanpa topic, offset, event ID, order ID, trace ID.

3. Wrong Log Level

Severity salah.

Dampak:

  • alert noise
  • error rate terlihat lebih buruk
  • engineer mengabaikan ERROR
  • WARN penting tertutup noise

4. Duplicate Error Logging

Exception yang sama dilog sebagai ERROR di banyak layer.

Dampak:

  • volume meningkat
  • incident terlihat lebih besar dari sebenarnya
  • deduplication sulit

5. Sensitive Data Leakage

Log menyimpan token, cookie, password, PII, request body, SQL parameter, atau payload event.

Dampak:

  • security incident
  • compliance issue
  • akses log harus dibatasi
  • retention menjadi risiko

6. Log Spam

Event terlalu sering dilog tanpa nilai diagnosis.

Dampak:

  • cost naik
  • query lambat
  • signal penting tenggelam
  • storage penuh

7. Logging on Hot Path with Blocking Sink

Logging memperlambat request.

Dampak:

  • latency naik
  • thread blocked
  • cascading degradation jika log backend lambat

8. Invalid Structured Log

JSON log tidak valid atau field berubah-ubah.

Dampak:

  • parser gagal
  • field tidak terindex
  • query tidak reliable

9. Timezone Mismatch

Log antar service memakai timezone berbeda.

Dampak:

  • timeline incident salah
  • RCA misleading

10. Context Leakage Across Threads

MDC tidak dibersihkan atau tidak dipropagasi benar.

Dampak:

  • log request A membawa context request B
  • security/audit interpretation salah

Mendeteksi Logging Failure

Logging failure sering baru terlihat saat incident. Jangan tunggu incident.

Cara mendeteksi:

Query Sampling

Ambil beberapa request trace ID dan cari log terkait.

Pertanyaan:

  • apakah semua log memiliki trace ID?
  • apakah request start/end ada?
  • apakah error punya business key?
  • apakah dependency failure punya dependency name?

Log Schema Validation

Validasi field wajib:

  • timestamp
  • level
  • service
  • environment
  • logger
  • message
  • event untuk structured event
  • trace/correlation ID jika request-bound

Error Review

Review top ERROR logs.

Pertanyaan:

  • apakah ERROR benar-benar error?
  • apakah duplicate?
  • apakah expected validation failure?
  • apakah missing stack trace?
  • apakah ada sensitive data?

Volume Review

Cari logger/event dengan volume tertinggi.

Pertanyaan:

  • apakah log ini berguna?
  • apakah level terlalu tinggi?
  • apakah bisa sampling?
  • apakah bisa menjadi metric saja?

Privacy Scan

Cari pola:

  • Authorization
  • Bearer
  • password
  • token
  • cookie
  • session
  • email
  • phone
  • credit/commercial data

Incident Drill

Ambil incident lama dan tanyakan:

  • log apa yang membantu?
  • log apa yang hilang?
  • log apa yang noisy?
  • field apa yang seharusnya ada?

Debugging dengan Logs

Logs paling berguna jika digunakan secara sistematis.

Step 1: Mulai dari Correlation Field

Gunakan:

trace_id
correlation_id
request_id
message_id
event_id
quote_id
order_id
process_instance_id

Jangan mulai dari keyword acak jika Anda punya ID.

Step 2: Susun Timeline

Urutkan berdasarkan event time.

Cari:

  • request start
  • validation
  • dependency call
  • state transition
  • exception
  • retry
  • fallback
  • response

Step 3: Bandingkan dengan Metrics

Logs menjelaskan detail. Metrics menjelaskan skala.

Pertanyaan:

  • apakah error ini individual atau sistemik?
  • apakah latency spike terjadi global?
  • apakah retry count naik?

Step 4: Hubungkan ke Trace

Gunakan trace ID untuk melihat causal path.

Pertanyaan:

  • span mana yang lambat?
  • apakah log error sejajar dengan span error?
  • apakah trace putus?

Step 5: Hubungkan ke Business State

Pertanyaan:

  • entity bisnis masuk state apa?
  • apakah order stuck?
  • apakah quote bisa retry?
  • apakah audit event ada?

Correctness Concern

Logging correctness berarti log mencerminkan kenyataan sistem.

Masalah correctness umum:

  • log success sebelum transaksi commit
  • log audit sebelum aksi benar-benar berhasil
  • log state transition sebelum state tersimpan
  • log retry failed padahal retry berikutnya sukses tanpa final status
  • log ERROR untuk expected business rejection
  • log status code salah karena ExceptionMapper mengubah response

Prinsip:

  • log final result di boundary yang tahu hasil final
  • hati-hati logging sebelum commit
  • bedakan attempted vs completed
  • gunakan event name yang jelas

Contoh:

order.submission.attempted
order.submission.completed
order.submission.failed

Jangan memakai order.submitted jika order belum benar-benar submitted.


Performance Concern

Logging dapat mempengaruhi performance.

Risiko:

  • string concatenation mahal walau level disabled
  • serialisasi object besar
  • logging request/response body
  • synchronous remote logging
  • stack trace generation mahal
  • excessive logging di loop/hot path
  • JSON encoding overhead

Prinsip Java:

log.debug("Calculated price for quoteId={}", quoteId);

Lebih baik daripada:

log.debug("Calculated price for quoteId=" + quoteId);

Parameterized logging menghindari string construction jika level tidak aktif, tergantung framework.

Namun structured logging dengan object field tetap harus hati-hati jika value construction mahal.


Security and Privacy Concern

Log adalah data production yang sering diakses banyak pihak. Karena itu log harus diperlakukan sebagai sensitive operational data.

Jangan log:

  • password
  • token
  • Authorization header
  • cookie
  • session ID
  • API key
  • full request body tanpa review
  • full response body tanpa review
  • raw SQL parameter sensitif
  • payment/financial confidential data
  • personal data tanpa kebutuhan dan policy

Gunakan:

  • allowlist field
  • masking
  • redaction
  • token hashing jika perlu correlation tanpa reveal
  • payload category, bukan payload raw
  • key category, bukan Redis key raw

Cost Concern

Log cost berasal dari:

  • volume
  • ingestion
  • parsing
  • indexing
  • retention
  • query
  • archive

Hal yang meningkatkan cost:

  • request start dan end log untuk semua endpoint high-QPS
  • DEBUG logs aktif
  • stack trace berulang
  • payload logging
  • high-cardinality fields di-index
  • noisy health check logs
  • repeated retry logs tanpa sampling

Cost bukan alasan untuk menghapus semua log. Cost adalah alasan untuk mendesain log dengan disiplin.


Operational Concern

Log harus berguna saat incident.

Operationally useful log memiliki:

  • event name
  • severity benar
  • correlation ID
  • business key jika relevan
  • dependency name jika dependency failure
  • error code jika gagal
  • latency/duration jika operation penting
  • result/status
  • linkability ke trace/metric/dashboard

Jika log hanya bisa dipahami oleh developer asli yang menulis code, log itu belum cukup operational.


Internal Verification Checklist

Gunakan checklist ini saat mempelajari codebase/team.

Log Format

  • Apakah log production berbentuk JSON atau plain text?
  • Apakah satu event menjadi satu log line?
  • Apakah stack trace diparse dengan benar?
  • Apakah timestamp memakai UTC?
  • Apakah ingestion time dan event time dibedakan?

Standard Fields

  • Apakah ada field service?
  • Apakah ada field environment?
  • Apakah ada field version atau build metadata?
  • Apakah ada field logger?
  • Apakah ada field thread?
  • Apakah ada field event?
  • Apakah ada field trace_id?
  • Apakah ada field correlation_id?
  • Apakah ada field tenant_id jika relevan?
  • Apakah ada business key seperti quote_id atau order_id saat relevan?

Log Level

  • Apakah ERROR benar-benar menunjukkan operation failure?
  • Apakah WARN digunakan untuk abnormal-but-recoverable condition?
  • Apakah INFO terlalu noisy?
  • Apakah DEBUG aktif di production?
  • Apakah health check logs membuat noise?

Request Logging

  • Apakah ada request start/end log?
  • Apakah route template dicatat?
  • Apakah status code dicatat?
  • Apakah latency dicatat?
  • Apakah request body dilog? Jika ya, kenapa dan bagaimana masking-nya?
  • Apakah sensitive headers difilter?

Exception Logging

  • Apakah stack trace muncul untuk unexpected error?
  • Apakah exception duplicate di banyak layer?
  • Apakah error code dicatat?
  • Apakah exception message aman?
  • Apakah validation/domain errors tidak memenuhi ERROR log secara berlebihan?

Dependency Logging

  • Apakah timeout downstream dilog dengan dependency name?
  • Apakah DB rollback/lock/deadlock terlihat?
  • Apakah Kafka/RabbitMQ DLQ event dilog?
  • Apakah Redis timeout/lock failure dilog?
  • Apakah Camunda failed job/correlation failure dilog?

Privacy/Security

  • Apakah Authorization header pernah masuk log?
  • Apakah cookie/session ID pernah masuk log?
  • Apakah PII masuk log?
  • Apakah request/response body masuk log?
  • Apakah SQL parameter masuk log?
  • Apakah audit log dipisahkan dari application log?

Pipeline

  • Log dikirim ke mana?
  • Apakah ada log collector/agent?
  • Apakah ada parsing failure?
  • Apakah ada dropped logs?
  • Berapa retention?
  • Siapa yang punya akses?
  • Apakah log volume dimonitor?

Internal CSG Verification

  • Apakah ada standard logging schema internal?
  • Apakah ada naming convention untuk event field?
  • Apakah correlation ID convention sudah ditentukan?
  • Apakah quote/order ID boleh masuk log?
  • Apakah tenant/customer ID boleh masuk log?
  • Apakah ada policy masking/redaction?
  • Apakah ada contoh service yang dianggap best practice?
  • Apakah ada incident lama yang menunjukkan gap logging?

PR Review Checklist

Saat review PR yang menambah log, tanyakan:

Purpose

  • Log ini menjawab pertanyaan production apa?
  • Apakah log ini untuk debugging, audit, operation, security, atau business lifecycle?
  • Apakah ini lebih cocok menjadi metric atau trace span daripada log?

Placement

  • Apakah log berada di boundary yang tepat?
  • Apakah log success dibuat setelah operasi benar-benar sukses?
  • Apakah log failure dibuat di tempat yang punya context cukup?
  • Apakah exception dilog sekali di boundary yang tepat?

Fields

  • Apakah ada event name?
  • Apakah ada trace/correlation ID via MDC?
  • Apakah ada business key saat relevan?
  • Apakah ada error code untuk failure?
  • Apakah ada dependency name untuk dependency failure?
  • Apakah ada duration untuk operation penting?

Level

  • Apakah level sesuai severity?
  • Apakah expected business rejection dicatat dengan level yang tepat?
  • Apakah retryable transient issue memakai WARN atau ERROR sesuai policy?
  • Apakah log ini akan noisy di production?

Safety

  • Apakah ada PII?
  • Apakah ada token/header/cookie/password?
  • Apakah ada payload besar?
  • Apakah ada SQL parameter sensitif?

Cost

  • Apakah log berada di high-QPS path?
  • Apakah log terjadi dalam loop?
  • Apakah stack trace akan muncul terlalu sering?
  • Apakah perlu sampling atau rate limiting?

Operability

  • Apakah log bisa dicari di backend?
  • Apakah field terindex?
  • Apakah log bisa dikorelasikan dengan metric/trace?
  • Apakah runbook/dashboard perlu diperbarui?

Mini Case Study: Log yang Tidak Bisa Dipakai Saat Incident

Incident:

Customer melaporkan order tidak masuk fulfillment.

Log yang tersedia:

ERROR Failed to submit

Masalah:

  • tidak ada order ID
  • tidak ada tenant ID
  • tidak ada trace ID
  • tidak ada dependency
  • tidak ada error code
  • tidak ada status final
  • tidak ada retry attempt
  • tidak ada timestamp timezone jelas

Engineer harus mencari manual lewat DB, event, dan guesswork.

Log yang seharusnya ada:

{
  "timestamp": "2026-07-11T14:20:10.011Z",
  "level": "ERROR",
  "service": "order-service",
  "event": "order.fulfillment.publish.failed",
  "message": "Failed to publish fulfillment command",
  "trace_id": "7f1d...",
  "correlation_id": "corr-...",
  "tenant_id": "tenant-123",
  "order_id": "O-91821",
  "dependency": "rabbitmq",
  "exchange": "fulfillment.command",
  "routing_key": "fulfillment.start",
  "error_code": "BROKER_PUBLISH_TIMEOUT",
  "retryable": true,
  "attempt": 3,
  "latency_ms": 3000,
  "exception_class": "java.util.concurrent.TimeoutException"
}

Dengan log ini, engineer bisa:

  • mencari semua event untuk order tersebut
  • melihat broker publish failure
  • cek RabbitMQ dashboard
  • cek retry/DLQ behavior
  • korelasikan dengan trace
  • hitung impact tenant/order lain
  • menentukan mitigation

Anti-Pattern Logging

1. Log as Comment

log.info("Inside method A");
log.info("Calling method B");
log.info("Done");

Ini biasanya noise. Log harus event-oriented, bukan komentar runtime untuk developer.

2. Log Without Context

log.error("Processing failed", e);

Lebih baik daripada tanpa stack trace, tetapi masih kurang jika tidak ada request/business context.

3. Log Full Payload

log.info("Request body: {}", body);

Berisiko PII, token, payload besar, dan cost.

4. Log and Swallow

catch (Exception e) {
    log.error("Failed", e);
}

Jika error ditelan tanpa recovery yang benar, sistem bisa corrupt atau silent failure.

5. Error Everywhere

Setiap layer mencatat exception yang sama sebagai ERROR.

Akibatnya satu failure terlihat seperti banyak failure.

6. Business Success Before Commit

log.info("Order submitted");
repository.save(order);

Jika save gagal, log menjadi bohong.

7. Raw Path as Main Identifier

/quotes/Q-123/pricing

Untuk query aggregate, gunakan route template:

/quotes/{quoteId}/pricing

Business key boleh field terpisah jika aman:

quote_id = Q-123

Expected Mastery Setelah Part Ini

Anda harus mampu:

  • menjelaskan perbedaan log, log event, dan log line
  • membedakan structured log, JSON log, dan plain text log
  • memahami field dasar log production
  • memahami fungsi timestamp, timezone, thread, logger, message, exception, dan context field
  • memahami kenapa log harus event-oriented dan context-rich
  • memahami failure mode logging seperti missing context, wrong level, duplicate exception, sensitive leakage, log spam, invalid JSON, timezone mismatch, dan MDC leakage
  • melakukan debugging awal menggunakan correlation ID, timeline, logs, metrics, dan traces
  • mereview PR logging dari sisi purpose, placement, fields, level, safety, cost, dan operability
  • membuat internal verification checklist untuk logging di service Java/JAX-RS enterprise

Penutup

Logging adalah signal yang paling mudah dibuat tetapi paling mudah dirusak. Log yang baik mempercepat incident response. Log yang buruk menambah noise, biaya, risiko privacy, dan kesalahan diagnosis.

Part berikutnya akan membahas ekosistem logging Java: SLF4J, Logback, Log4j2, JUL, bridge libraries, logger naming, async appender, JSON encoder, MDC, marker, parameterized logging, exception logging, runtime log level change, dan integrasinya dengan JAX-RS/Jakarta REST.

Lesson Recap

You just completed lesson 04 in start here. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.