Documentation
¶
Overview ¶
Package otellog adalah wrapper tipis di atas go-lib RunLogger yang otomatis menambahkan trace.id dan span.id ke setiap log entry, sekaligus mengirim log via OTEL Log SDK → Collector → Elasticsearch.
Index ¶
- Constants
- func Activity(ctx goravelhttp.Context, m golib.Map)
- func AddFields(ctx context.Context, fields ...golib.Map) context.Context
- func CallerName(skip int) string
- func ContextWithTraceParent(ctx context.Context, traceparent string) context.Context
- func DBSystem() string
- func EnrichMap(ctx goravelhttp.Context, m map[string]any) map[string]any
- func Flush(ctx context.Context) error
- func GoContext(ctx goravelhttp.Context) context.Context
- func IsSensitiveKey(key string) bool
- func MaskJSON(body []byte, maxBytes int) string
- func MaskValue(v any) any
- func RegisterSensitiveKeys(keys ...string)
- func RegisterTypeName(goName, display string)
- func ServerMiddleware(opts ...MiddlewareOption) goravelhttp.Middleware
- func SetDBAttrs(ctx context.Context, statement string)
- func SetDBPaginateAttrs(ctx context.Context, statement string, page, limit int, rowsReturned int64)
- func SetDBSystem(system string)
- func Trace(ctx context.Context, fields ...golib.Map) (context.Context, func(*error))
- func TraceDB(ctx context.Context, table, operation string) (context.Context, func(*error))
- func TraceDBAuto(ctx context.Context, table, operation string) (context.Context, func(*error))
- func TraceFunc(ctx context.Context, name string, fields ...golib.Map) (context.Context, func(*error))
- func TraceParent(ctx context.Context) string
- func WithRequestFields(ctx context.Context, fields golib.Map) context.Context
- type Logger
- type MiddlewareOption
- func WithActivityLog(enabled bool) MiddlewareOption
- func WithBodyFields(specs ...string) MiddlewareOption
- func WithMaxBodyBytes(n int) MiddlewareOption
- func WithMetrics(enabled bool) MiddlewareOption
- func WithSkipPaths(paths ...string) MiddlewareOption
- func WithTrustIncomingTrace(trust bool) MiddlewareOption
- type WorkerLogger
Constants ¶
const MaskedValue = "***"
MaskedValue adalah pengganti nilai untuk field sensitif.
Variables ¶
This section is empty.
Functions ¶
func Activity ¶
func Activity(ctx goravelhttp.Context, m golib.Map)
Activity emits an HTTP activity log via OTEL SDK only (does not write to runtime.log). Use in middleware after calling Next() to capture full request/response with real trace.id.
func AddFields ¶ added in v1.1.12
AddFields menambahkan field bisnis (mis. refno, order_id, pn_maker) ke context:
- disimpan sebagai request fields, sehingga otomatis ikut ke setiap log otellog.Runtime / RuntimeCtx / Activity yang memakai context ini
- dipasang sebagai attribute di span aktif pada ctx, supaya bisa dicari di Jaeger/APM
Nilai di-mask lewat MaskValue (key sensitif jadi "***"). Nilai nil atau string kosong dilewati. Field yang sudah ada di context ditimpa bila key-nya sama. Pakai context hasil kembalian untuk pemanggilan berikutnya:
ctx = otellog.AddFields(ctx, log.Map{"refno": req.Refno, "order_id": id})
func CallerName ¶ added in v1.1.11
CallerName mengembalikan nama "<Struct>.<Func>" fungsi pada kedalaman stack skip (0 = fungsi yang memanggil CallerName, 1 = pemanggilnya, dst.). Untuk helper/wrapper span sendiri:
func startSpan(ctx goravelhttp.Context) (context.Context, trace.Span) {
return otel.Tracer(...).Start(otellog.GoContext(ctx), otellog.CallerName(1))
}
func ContextWithTraceParent ¶ added in v1.1.13
ContextWithTraceParent mengembalikan ctx yang membawa span context remote dari traceparent, sehingga span yang dibuat dari ctx ini (mis. otellog.Trace di Handle job) menjadi CHILD dari span pengirim dan berada di trace.id yang sama. traceparent kosong/invalid → ctx apa adanya (proses memulai trace baru).
ctx = otellog.ContextWithTraceParent(ctx, j.TraceParent) ctx, done := otellog.Trace(ctx)
func DBSystem ¶ added in v1.1.15
func DBSystem() string
DBSystem mengembalikan nilai db.system yang dipakai span database: override dari SetDBSystem bila ada, jika tidak diturunkan dari env DB_CONNECTION (nama koneksi Goravel). Kosong bila tidak bisa ditentukan — attribute tidak dipasang.
func GoContext ¶
func GoContext(ctx goravelhttp.Context) context.Context
GoContext mengambil enriched Go context (dengan OTEL span) dari goravelhttp.Context. Gunakan di controller saat memanggil usecase agar trace menyambung. Fallback ke ctx.Context() jika OTEL belum di-set.
func IsSensitiveKey ¶ added in v1.1.10
IsSensitiveKey melaporkan apakah nilai dengan key ini harus di-mask.
func MaskJSON ¶ added in v1.1.10
MaskJSON mem-parse body JSON, me-mask field sensitif, lalu memotong hasilnya ke maxBytes (0 = tanpa batas). Body non-JSON dikembalikan apa adanya (terpotong), karena tidak bisa diidentifikasi field-nya.
func MaskValue ¶ added in v1.1.10
MaskValue mengembalikan salinan v dengan semua nilai ber-key sensitif diganti MaskedValue, rekursif ke map dan slice. Nilai asli tidak dimodifikasi.
func RegisterSensitiveKeys ¶ added in v1.1.10
func RegisterSensitiveKeys(keys ...string)
RegisterSensitiveKeys menambah key yang harus di-mask (pencocokan exact, setelah normalisasi). Panggil sekali saat boot service, mis. untuk field domain khusus: otellog.RegisterSensitiveKeys("namaIbuKandung", "noHp").
func RegisterTypeName ¶ added in v1.1.11
func RegisterTypeName(goName, display string)
RegisterTypeName mengatur nama tampil tipe receiver untuk Trace, TraceDBAuto, CallerName, dan otelmetric.Record — untuk akronim yang tidak bisa ditebak:
func init() { otellog.RegisterTypeName("glDebitUsecase", "GLDebitUsecase") }
func ServerMiddleware ¶ added in v1.1.10
func ServerMiddleware(opts ...MiddlewareOption) goravelhttp.Middleware
ServerMiddleware menggantikan pasangan middleware OtelMetrics + OtelActivity dan startSpan di controller. Untuk setiap request ia:
- Extract traceparent dari header (bisa dimatikan, lihat WithTrustIncomingTrace)
- Membuat span SERVER dan menyimpannya ke context ("otelSpan", "otelContext"), sehingga otellog.Runtime / otellog.GoContext di controller langsung tersambung
- Mencatat HTTP metrics (total, durasi, active)
- Setelah handler selesai: set http.status_code, status Error untuk 5xx/panic, lalu kirim activity log dengan body yang sudah di-mask & dipotong
Pasang PALING AWAL, sebelum middleware bisnis (auth, PreRequest, dll.), supaya request yang ditolak middleware tersebut tetap punya trace:
facades.Route().Middleware(otellog.ServerMiddleware(), middleware.PreRequest).Group(...)
Di controller, nama span bisa diperjelas:
trace.SpanFromContext(otellog.GoContext(ctx)).SetName("OrderController.Create")
func SetDBAttrs ¶
SetDBAttrs menyimpan db.statement ke span aktif di ctx. Gunakan untuk INSERT, UPDATE, DELETE, atau single SELECT.
ctx, done := otellog.TraceDB(ctx, "mst_rekanan", "UPDATE")
defer done(&err)
otellog.SetDBAttrs(ctx, query.ToRawSql().Update("status", val))
func SetDBPaginateAttrs ¶
SetDBPaginateAttrs menyimpan db.statement + pagination + rows_returned ke span aktif di ctx. Panggil setelah Paginate selesai dengan stmt yang diambil sebelum eksekusi.
ctx, done := otellog.TraceDB(ctx, "mst_rekanan", "SELECT") defer done(&err) stmt := query.ToRawSql().Find(&list) _ = query.Paginate(page, limit, &list, &total) otellog.SetDBPaginateAttrs(ctx, stmt, page, limit, total)
func SetDBSystem ¶ added in v1.1.15
func SetDBSystem(system string)
SetDBSystem menetapkan nilai attribute db.system untuk semua span TraceDB / TraceDBAuto (mis. "postgresql", "mysql"). Tanpa pemanggilan ini, nilai diturunkan dari env DB_CONNECTION (lihat DBSystem). String kosong mengembalikan ke perilaku env.
db.system dipakai Kibana APM untuk mengisi span.subtype, sehingga span database tampil dengan nama database ("postgresql") di legend dan filter, bukan "db" generik.
func Trace ¶ added in v1.1.11
Trace sama dengan TraceFunc, tetapi nama span diambil otomatis dari fungsi pemanggil dengan format "<Struct>.<Func>" (atau "<pkg>.<Func>" untuk fungsi tanpa receiver). Contoh: method (*orderNotarisUsecase).CreateOrderNotaris → "OrderNotarisUsecase.CreateOrderNotaris". Closure (.func1) diabaikan sehingga nama tetap nama method yang membungkusnya.
func (u *orderNotarisUsecase) CreateOrderNotaris(ctx context.Context, req Req) (res Res, err error) {
ctx, done := otellog.Trace(ctx)
defer done(&err)
defer otelmetric.Record(ctx)()
...
}
Harus dipanggil LANGSUNG dari fungsi yang ingin di-trace. Untuk wrapper (mis. helper startSpan di controller) pakai TraceFunc(ctx, CallerName(1)). Akronim pada nama struct (glDebitUsecase → GLDebitUsecase) diatur via RegisterTypeName.
func TraceDB ¶
TraceDB membuat DB span (kind CLIENT) bernama "db.<table>.<operation>". Untuk nama otomatis "<Repository>.<Func>" pakai TraceDBAuto. Gunakan dengan named return error dan defer:
func (r *Repo) GetList(ctx context.Context, ...) (result []Model, err error) {
ctx, done := otellog.TraceDB(ctx, "nama_tabel", "SELECT")
defer done(&err)
...
}
gorm.ErrRecordNotFound (termasuk yang dibungkus %w) tidak dicatat sebagai error; span diberi attribute db.result="not_found".
func TraceDBAuto ¶ added in v1.1.11
TraceDBAuto sama dengan TraceDB, tetapi nama span diambil otomatis dari fungsi pemanggil, mis. (*orderNotarisRepository).GetListOrderNotaris → "OrderNotarisRepository.GetListOrderNotaris". Tabel & operasi tetap tersimpan sebagai attribute db.table / db.operation.
ctx, done := otellog.TraceDBAuto(ctx, constants.TableOrderNotaris, "SELECT") defer done(&err)
func TraceFunc ¶
func TraceFunc(ctx context.Context, name string, fields ...golib.Map) (context.Context, func(*error))
TraceFunc membuat span + log error otomatis untuk satu fungsi, dengan nama span eksplisit. Untuk nama otomatis "<Struct>.<Func>" pakai Trace. Gunakan dengan named return error dan defer:
func (u *Usecase) MyFunc(ctx context.Context, req Req) (resp Resp, err error) {
ctx, done := otellog.TraceFunc(ctx, "Usecase.MyFunc", log.Map{"key": val})
defer done(&err)
...
}
Error bisnis stderr (kode 01, 02, 03, 05, X0, X1) tidak dicatat sebagai error (tanpa RecordError, status Error, dan log Error); error sistem tetap dicatat.
fields opsional: dipasang sebagai attribute span dan digabung ke setiap log yang memakai ctx hasil kembalian (termasuk log error dari done), mis. log.Map{"refno": req.Refno}. Nilai sensitif di-mask, nilai kosong dilewati.
func TraceParent ¶ added in v1.1.13
TraceParent mengambil header W3C traceparent dari span aktif di ctx, untuk diteruskan ke proses asinkron (argumen job queue, pesan Kafka, dll.). String kosong bila ctx tidak membawa span (mis. OTEL mati) — aman diteruskan apa adanya.
{Type: "string", Value: otellog.TraceParent(ctx)}
func WithRequestFields ¶
WithRequestFields menyimpan field request ke dalam Go context. Field ini otomatis di-merge ke setiap log call yang menggunakan context tersebut, tanpa perlu ditulis ulang di setiap Info/Warning/Error.
Field yang sudah ada di context digabung (key yang sama ditimpa oleh fields); map milik context sebelumnya tidak dimodifikasi. Untuk field bisnis yang juga perlu muncul sebagai attribute span, pakai AddFields.
Types ¶
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
func Runtime ¶
func Runtime(ctx goravelhttp.Context) *Logger
Runtime — pakai di controller yang punya goravelhttp.Context. Otomatis mengambil enriched context (dengan request fields) jika sudah di-set oleh OtelPropagation atau OtelRequestFields middleware.
func RuntimeCtx ¶
RuntimeCtx — pakai di usecase/repository yang punya context.Context.
type MiddlewareOption ¶ added in v1.1.10
type MiddlewareOption func(*middlewareConfig)
MiddlewareOption mengatur perilaku ServerMiddleware.
func WithActivityLog ¶ added in v1.1.10
func WithActivityLog(enabled bool) MiddlewareOption
WithActivityLog menyalakan/mematikan activity log OTEL. Default true.
func WithBodyFields ¶ added in v1.1.12
func WithBodyFields(specs ...string) MiddlewareOption
WithBodyFields mengambil field top-level dari request body (JSON/form) dan menjadikannya field pencarian: attribute span SERVER, field di log activity, dan request fields yang ikut ke semua log dalam request ini (otellog.Runtime / RuntimeCtx) serta ke span/log turunannya lewat GoContext.
Tiap spesifikasi berbentuk "key" atau "key:nama_field". Key dicocokkan tanpa peduli huruf besar/kecil dan tanda '_', '-', '.', jadi "refnoOrder" cocok dengan "refno_order". Nilai kosong, non-skalar, atau ber-key sensitif dilewati.
otellog.WithBodyFields("refno", "refnoPrakarsa:refno_prakarsa", "refnoOrder:refno_order", "orderId:order_id")
Field yang baru diketahui setelah handler berjalan (mis. hasil query) ditambahkan dengan otellog.AddFields.
func WithMaxBodyBytes ¶ added in v1.1.10
func WithMaxBodyBytes(n int) MiddlewareOption
WithMaxBodyBytes batas ukuran requestBody/responseBody di activity log (setelah masking). Default 10000 byte.
func WithMetrics ¶ added in v1.1.10
func WithMetrics(enabled bool) MiddlewareOption
WithMetrics menyalakan/mematikan HTTP metrics (otelmetric.RecordHTTP). Default true.
func WithSkipPaths ¶ added in v1.1.10
func WithSkipPaths(paths ...string) MiddlewareOption
WithSkipPaths mengganti daftar path yang tidak di-trace/log/metric. Default: /ping, /favicon.ico.
func WithTrustIncomingTrace ¶ added in v1.1.10
func WithTrustIncomingTrace(trust bool) MiddlewareOption
WithTrustIncomingTrace menentukan apakah header traceparent/tracestate dari request masuk dipakai sebagai parent. Default true (service di belakang gateway). Set false di gateway/edge supaya client eksternal tidak bisa menyuntik trace ID dan keputusan sampling — gateway selalu jadi root span.
type WorkerLogger ¶ added in v1.1.16
type WorkerLogger struct {
// contains filtered or unexported fields
}
WorkerLogger menulis log job/worker ke worker.log lokal dan OTEL sekaligus.
func Worker ¶ added in v1.1.16
func Worker(ctx context.Context) *WorkerLogger
Worker mengembalikan logger untuk job/worker. Satu panggilan menulis ke:
- worker.log lokal (golib.Worker) — perilaku lama, tetap dipertahankan
- runtime.log lokal + OTEL collector → Kibana (RuntimeCtx), membawa trace.id/span.id dan request fields (AddFields) dari ctx, sehingga log bisa dikorelasikan dengan span job/usecase/ESB
Pakai ctx yang membawa span (hasil otellog.Trace di Handle), bukan ctx awal:
traceCtx, done := otellog.Trace(ctx, log.Map{"order_id": j.OrderID})
defer done(&err)
otellog.Worker(traceCtx).Info(log.Map{"message": "Job started"})
func (*WorkerLogger) Error ¶ added in v1.1.16
func (w *WorkerLogger) Error(m golib.Map)
Error: runtime.log + OTEL level ERROR (tidak ditulis ke worker.log, sama seperti golib.Runtime(ctx).Error yang digantikannya).
func (*WorkerLogger) Info ¶ added in v1.1.16
func (w *WorkerLogger) Info(m golib.Map)
Info: OTEL level INFO + worker.log. otellog dipanggil lebih dulu karena ia menyalin map, sedangkan golib.Worker menambahkan traceID/identifier langsung ke map milik caller.
func (*WorkerLogger) Warning ¶ added in v1.1.16
func (w *WorkerLogger) Warning(m golib.Map)
Warning: OTEL level WARN; worker.log lokal tetap Info (golib.Worker hanya punya Info).