@@ -455,8 +455,12 @@ type LogWriter struct {
455455 err error
456456 // minSyncInterval is the minimum duration between syncs.
457457 minSyncInterval durationFunc
458- fsyncLatency prometheus.Histogram
459- pending []* block
458+
459+ // Enhanced WAL metrics for all filesystem operations
460+ walFileMetrics WALFileMetrics
461+ // Directory type for metrics recording
462+ directoryType DirectoryType
463+ pending []* block
460464 // Pushing and popping from pendingSyncs does not require flusher mutex to
461465 // be held.
462466 pendingSyncs pendingSyncs
@@ -486,10 +490,52 @@ type LogWriter struct {
486490 emitFragment func (n int , p []byte ) (remainingP []byte )
487491}
488492
493+ // DirectoryType identifies which WAL directory an operation targets
494+ type DirectoryType int
495+
496+ const (
497+ // DirectoryPrimary indicates operation targets the primary WAL directory
498+ DirectoryPrimary DirectoryType = iota
499+ // DirectorySecondary indicates operation targets the secondary WAL directory
500+ DirectorySecondary
501+ // DirectoryUnknown indicates directory context is unknown or not applicable
502+ DirectoryUnknown
503+ )
504+
505+ // String returns the string representation of DirectoryType.
506+ func (d DirectoryType ) String () string {
507+ switch d {
508+ case DirectoryPrimary :
509+ return "Primary"
510+ case DirectorySecondary :
511+ return "Secondary"
512+ case DirectoryUnknown :
513+ return "Unknown"
514+ default :
515+ return "Invalid"
516+ }
517+ }
518+
519+ // WALFileMetrics contains all latency histograms for individual WAL file operations
520+ type WALFileMetrics struct {
521+ CreateLatency prometheus.Histogram // File creation operations
522+ WriteLatency prometheus.Histogram // Write operations
523+ FsyncLatency prometheus.Histogram // Fsync operations
524+ CloseLatency prometheus.Histogram // File close operations
525+ StatLatency prometheus.Histogram // File stat operations
526+ OpenDirLatency prometheus.Histogram // Directory open operations
527+ }
528+
489529// LogWriterConfig is a struct used for configuring new LogWriters
490530type LogWriterConfig struct {
491531 WALMinSyncInterval durationFunc
492- WALFsyncLatency prometheus.Histogram
532+
533+ // Directory type for this LogWriter (Primary, Secondary, or Unknown)
534+ DirectoryType DirectoryType
535+
536+ // Enhanced WAL metrics for this directory
537+ WALFileMetrics WALFileMetrics
538+
493539 // QueueSemChan is an optional channel to pop from when popping from
494540 // LogWriter.flusher.syncQueue. It functions as a semaphore that prevents
495541 // the syncQueue from overflowing (which will cause a panic). All production
@@ -581,7 +627,8 @@ func NewLogWriter(
581627
582628 f := & r .flusher
583629 f .minSyncInterval = logWriterConfig .WALMinSyncInterval
584- f .fsyncLatency = logWriterConfig .WALFsyncLatency
630+ f .walFileMetrics = logWriterConfig .WALFileMetrics
631+ f .directoryType = logWriterConfig .DirectoryType
585632
586633 go func () {
587634 pprof .Do (context .Background (), walSyncLabels , r .flushLoop )
@@ -725,9 +772,9 @@ func (w *LogWriter) flushLoop(context.Context) {
725772 writtenOffset += uint64 (len (data ))
726773 synced , syncLatency , bytesWritten , err := w .flushPending (data , pending , snap )
727774 f .Lock ()
728- if synced && f .fsyncLatency != nil {
775+ if synced && f .walFileMetrics . FsyncLatency != nil {
729776 w .syncedOffset .Store (writtenOffset )
730- f .fsyncLatency .Observe (float64 (syncLatency ))
777+ f .walFileMetrics . FsyncLatency .Observe (float64 (syncLatency ))
731778 }
732779 f .err = err
733780 if f .err != nil {
@@ -784,7 +831,12 @@ func (w *LogWriter) flushPending(
784831 }
785832 if n := len (data ); err == nil && n > 0 {
786833 bytesWritten += int64 (n )
834+ // Measure write latency
835+ writeStart := crtime .NowMono ()
787836 _ , err = w .w .Write (data )
837+ if writeLatency := writeStart .Elapsed (); w .flusher .walFileMetrics .WriteLatency != nil {
838+ w .flusher .walFileMetrics .WriteLatency .Observe (float64 (writeLatency ))
839+ }
788840 }
789841
790842 synced = ! snap .empty ()
@@ -811,7 +863,13 @@ func (w *LogWriter) syncWithLatency() (time.Duration, error) {
811863}
812864
813865func (w * LogWriter ) flushBlock (b * block ) error {
814- if _ , err := w .w .Write (b .buf [b .flushed :]); err != nil {
866+ // Measure write latency for block flush
867+ writeStart := crtime .NowMono ()
868+ _ , err := w .w .Write (b .buf [b .flushed :])
869+ if writeLatency := writeStart .Elapsed (); w .flusher .walFileMetrics .WriteLatency != nil {
870+ w .flusher .walFileMetrics .WriteLatency .Observe (float64 (writeLatency ))
871+ }
872+ if err != nil {
815873 return err
816874 }
817875 b .written .Store (0 )
@@ -885,8 +943,8 @@ func (w *LogWriter) closeInternal(lastQueuedRecord PendingSyncIndex) error {
885943 syncLatency , err = w .syncWithLatency ()
886944 }
887945 f .Lock ()
888- if err == nil && f .fsyncLatency != nil {
889- f .fsyncLatency .Observe (float64 (syncLatency ))
946+ if err == nil && f .walFileMetrics . FsyncLatency != nil {
947+ f .walFileMetrics . FsyncLatency .Observe (float64 (syncLatency ))
890948 }
891949 free := w .free .blocks
892950 f .Unlock ()
@@ -897,7 +955,12 @@ func (w *LogWriter) closeInternal(lastQueuedRecord PendingSyncIndex) error {
897955 w .pendingSyncsBackingIndex .externalSyncQueueCallback (lastQueuedRecord , err )
898956 }
899957 if w .c != nil {
958+ // Measure close latency
959+ closeStart := crtime .NowMono ()
900960 cerr := w .c .Close ()
961+ if closeLatency := closeStart .Elapsed (); w .flusher .walFileMetrics .CloseLatency != nil {
962+ w .flusher .walFileMetrics .CloseLatency .Observe (float64 (closeLatency ))
963+ }
901964 w .c = nil
902965 err = firstError (err , cerr )
903966 }
0 commit comments