LogSlowOperation logs a slow operation with structured fields including trace ID. It only logs if the operation duration exceeds the configured threshold. Parameters: - operation: the type of operation (e.g., "query", "mutation", "backup") - opType: specific type within the operation (e.g., "dql", "
(ctx context.Context, operation, opType, payload string, latency *SlowOperationLatency)
| 144 | // - opType: specific type within the operation (e.g., "dql", "graphql") |
| 145 | // - payload: the operation payload (e.g., query text) - will be truncated if too long |
| 146 | func LogSlowOperation(ctx context.Context, operation, opType, payload string, latency *SlowOperationLatency) { |
| 147 | threshold := WorkerConfig.SlowQueryLogThreshold |
| 148 | if threshold <= 0 { |
| 149 | return |
| 150 | } |
| 151 | |
| 152 | total := latency.Total() |
| 153 | if total < threshold { |
| 154 | return |
| 155 | } |
| 156 | |
| 157 | fields := []zap.Field{ |
| 158 | zap.String("operation", operation), |
| 159 | zap.String("type", opType), |
| 160 | zap.Duration("total", total), |
| 161 | zap.Duration("parsing", latency.Parsing), |
| 162 | zap.Duration("processing", latency.Processing), |
| 163 | zap.Duration("encoding", latency.Encoding), |
| 164 | } |
| 165 | |
| 166 | // Extract trace ID from context if available |
| 167 | span := trace.SpanFromContext(ctx) |
| 168 | if span.SpanContext().IsValid() { |
| 169 | fields = append(fields, |
| 170 | zap.String("trace_id", span.SpanContext().TraceID().String()), |
| 171 | zap.String("span_id", span.SpanContext().SpanID().String()), |
| 172 | ) |
| 173 | } |
| 174 | |
| 175 | // Truncate payload for logging (avoid huge log entries) |
| 176 | if len(payload) > 1000 { |
| 177 | payload = payload[:1000] + "...[truncated]" |
| 178 | } |
| 179 | fields = append(fields, zap.String("payload", payload)) |
| 180 | |
| 181 | slowOperationLogger.Warn("slow operation", fields...) |
| 182 | } |