@@ -115,6 +115,11 @@ func (c *bcachefsCollector) Update(ch chan<- prometheus.Metric) error {
115115 c .logger .Debug ("failed to parse counters" , "uuid" , uuid , "err" , err )
116116 }
117117
118+ // Parse btree_write_stats
119+ if err := c .parseBtreeWriteStats (ch , fsPath , uuid ); err != nil {
120+ c .logger .Debug ("failed to parse btree_write_stats" , "uuid" , uuid , "err" , err )
121+ }
122+
118123 // Parse device stats
119124 if err := c .parseDevices (ch , fsPath , uuid ); err != nil {
120125 c .logger .Debug ("failed to parse devices" , "uuid" , uuid , "err" , err )
@@ -633,3 +638,80 @@ func (c *bcachefsCollector) parseDeviceIOErrors(ch chan<- prometheus.Metric, dev
633638
634639 return scanner .Err ()
635640}
641+
642+ // parseBtreeWriteStats parses the btree_write_stats file.
643+ // Format:
644+ //
645+ // nr size
646+ // initial: 19088 108k
647+ // init_next_bset: 6647 23.5k
648+ // cache_reclaim: 0 0
649+ // journal_reclaim: 541080 405
650+ // interior: 16788 354
651+ func (c * bcachefsCollector ) parseBtreeWriteStats (ch chan <- prometheus.Metric , fsPath , uuid string ) error {
652+ const subsystem = "bcachefs"
653+
654+ file , err := os .Open (filepath .Join (fsPath , "btree_write_stats" ))
655+ if err != nil {
656+ return err
657+ }
658+ defer file .Close ()
659+
660+ scanner := bufio .NewScanner (file )
661+ lineNum := 0
662+ for scanner .Scan () {
663+ lineNum ++
664+ line := scanner .Text ()
665+
666+ // Skip header line
667+ if lineNum == 1 {
668+ continue
669+ }
670+
671+ fields := strings .Fields (line )
672+ if len (fields ) < 3 {
673+ continue
674+ }
675+
676+ writeType := strings .TrimSuffix (fields [0 ], ":" )
677+ nrStr := fields [1 ]
678+ sizeStr := fields [2 ]
679+
680+ nr , err := strconv .ParseFloat (nrStr , 64 )
681+ if err != nil {
682+ c .logger .Debug ("failed to parse btree_write_stats nr" , "type" , writeType , "err" , err )
683+ continue
684+ }
685+
686+ size , err := parseHumanReadableBytes (sizeStr )
687+ if err != nil {
688+ c .logger .Debug ("failed to parse btree_write_stats size" , "type" , writeType , "err" , err )
689+ continue
690+ }
691+
692+ ch <- prometheus .MustNewConstMetric (
693+ prometheus .NewDesc (
694+ prometheus .BuildFQName (namespace , subsystem , "btree_writes_total" ),
695+ "Number of btree writes by type." ,
696+ []string {"uuid" , "type" },
697+ nil ,
698+ ),
699+ prometheus .CounterValue ,
700+ nr ,
701+ uuid , writeType ,
702+ )
703+ ch <- prometheus .MustNewConstMetric (
704+ prometheus .NewDesc (
705+ prometheus .BuildFQName (namespace , subsystem , "btree_write_average_size_bytes" ),
706+ "Average btree write size by type." ,
707+ []string {"uuid" , "type" },
708+ nil ,
709+ ),
710+ prometheus .GaugeValue ,
711+ size ,
712+ uuid , writeType ,
713+ )
714+ }
715+
716+ return scanner .Err ()
717+ }
0 commit comments