@@ -3,9 +3,12 @@ package daemon
33import (
44 "context"
55 "encoding/json"
6+ "fmt"
67 "log/slog"
78 "os"
9+ "path/filepath"
810 "strconv"
11+ "time"
912
1013 "github.com/google/uuid"
1114 "github.com/malamtime/cli/model"
@@ -22,6 +25,7 @@ type CCOtelProcessor struct {
2225 config model.ShellTimeConfig
2326 endpoint model.Endpoint
2427 hostname string
28+ debug bool
2529}
2630
2731// NewCCOtelProcessor creates a new CCOtel processor
@@ -31,20 +35,55 @@ func NewCCOtelProcessor(config model.ShellTimeConfig) *CCOtelProcessor {
3135 hostname = "unknown"
3236 }
3337
38+ debug := config .CCOtel != nil && config .CCOtel .Debug != nil && * config .CCOtel .Debug
39+
3440 return & CCOtelProcessor {
3541 config : config ,
3642 endpoint : model.Endpoint {
3743 Token : config .Token ,
3844 APIEndpoint : config .APIEndpoint ,
3945 },
4046 hostname : hostname ,
47+ debug : debug ,
48+ }
49+ }
50+
51+ // writeDebugFile appends JSON-formatted data to a debug file
52+ func (p * CCOtelProcessor ) writeDebugFile (filename string , data interface {}) {
53+ debugDir := filepath .Join (os .TempDir (), "shelltime" )
54+ if err := os .MkdirAll (debugDir , 0755 ); err != nil {
55+ slog .Error ("CCOtel: Failed to create debug directory" , "error" , err )
56+ return
57+ }
58+
59+ filePath := filepath .Join (debugDir , filename )
60+ f , err := os .OpenFile (filePath , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0644 )
61+ if err != nil {
62+ slog .Error ("CCOtel: Failed to open debug file" , "error" , err , "path" , filePath )
63+ return
64+ }
65+ defer f .Close ()
66+
67+ jsonData , err := json .MarshalIndent (data , "" , " " )
68+ if err != nil {
69+ slog .Error ("CCOtel: Failed to marshal debug data" , "error" , err )
70+ return
71+ }
72+
73+ timestamp := time .Now ().Format (time .RFC3339 )
74+ if _ , err := f .WriteString (fmt .Sprintf ("\n --- %s ---\n %s\n " , timestamp , jsonData )); err != nil {
75+ slog .Error ("CCOtel: Failed to write debug data" , "error" , err )
4176 }
4277}
4378
4479// ProcessMetrics receives OTEL metrics and forwards to backend immediately
4580func (p * CCOtelProcessor ) ProcessMetrics (ctx context.Context , req * collmetricsv1.ExportMetricsServiceRequest ) (* collmetricsv1.ExportMetricsServiceResponse , error ) {
4681 slog .Debug ("CCOtel: Processing metrics request" , "resourceMetricsCount" , len (req .GetResourceMetrics ()))
4782
83+ if p .debug {
84+ p .writeDebugFile ("ccotel-debug-metrics.txt" , req )
85+ }
86+
4887 for _ , rm := range req .GetResourceMetrics () {
4988 resource := rm .GetResource ()
5089
@@ -94,6 +133,10 @@ func (p *CCOtelProcessor) ProcessMetrics(ctx context.Context, req *collmetricsv1
94133func (p * CCOtelProcessor ) ProcessLogs (ctx context.Context , req * collogsv1.ExportLogsServiceRequest ) (* collogsv1.ExportLogsServiceResponse , error ) {
95134 slog .Debug ("CCOtel: Processing logs request" , "resourceLogsCount" , len (req .GetResourceLogs ()))
96135
136+ if p .debug {
137+ p .writeDebugFile ("ccotel-debug-logs.txt" , req )
138+ }
139+
97140 for _ , rl := range req .GetResourceLogs () {
98141 resource := rl .GetResource ()
99142
0 commit comments