Skip to content

Commit deb2230

Browse files
github-actions[bot]actions-userclaude
authored
[log] Add debug logging to parser, workflow, and cli packages (#19110)
* Add debug logging to parser, workflow, and cli packages Enhance five files with meaningful debug logging to improve troubleshooting: - pkg/parser/schedule_cron_detection.go: log cron classification results (daily/hourly) and invalid expression detection - pkg/parser/import_cycle.go: log DFS cycle detection traversal using existing importLog, including cycle path discovery - pkg/parser/schema_compiler.go: log schema selection and validation outcomes in validateWithSchema using schemaCompilerLog - pkg/workflow/codex_mcp.go: log TOML and JSON MCP config rendering for custom tools with rewrite_localhost context using codexMCPLog - pkg/cli/deps_report.go: log go.mod parsing and JSON report generation using depsReportLog Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: trigger CI checks --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent e16430e commit deb2230

5 files changed

Lines changed: 38 additions & 5 deletions

File tree

pkg/cli/deps_report.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ func DisplayDependencyReport(report *DependencyReport) {
190190

191191
// DisplayDependencyReportJSON outputs the dependency report in JSON format
192192
func DisplayDependencyReportJSON(report *DependencyReport) error {
193+
depsReportLog.Printf("Generating JSON dependency report: %d total, %d outdated, %d advisories", report.TotalDeps, len(report.Outdated), len(report.Advisories))
194+
193195
// Calculate percentages
194196
outdatedPercentage := 0.0
195197
if report.DirectDeps > 0 {
@@ -270,6 +272,8 @@ type DependencyInfoWithIndirect struct {
270272

271273
// parseGoModWithIndirect parses go.mod including indirect dependencies
272274
func parseGoModWithIndirect(path string) ([]DependencyInfoWithIndirect, error) {
275+
depsReportLog.Printf("Parsing go.mod file: %s", path)
276+
273277
content, err := os.ReadFile(path)
274278
if err != nil {
275279
return nil, err
@@ -313,6 +317,7 @@ func parseGoModWithIndirect(path string) ([]DependencyInfoWithIndirect, error) {
313317
}
314318
}
315319

320+
depsReportLog.Printf("Parsed go.mod: %d total dependencies", len(deps))
316321
return deps, nil
317322
}
318323

pkg/parser/import_cycle.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import "sort"
88
// findCyclePath uses DFS to find a complete cycle path in the dependency graph.
99
// Returns a path showing the full chain including the back-edge (e.g., ["b.md", "c.md", "d.md", "b.md"]).
1010
func findCyclePath(cycleNodes map[string]bool, dependencies map[string][]string) []string {
11+
importLog.Printf("Finding cycle path among %d cycle nodes", len(cycleNodes))
12+
1113
// Pick any node in the cycle as a starting point (use sorted order for determinism)
1214
var startNode string
1315
sortedNodes := make([]string, 0, len(cycleNodes))
@@ -18,16 +20,21 @@ func findCyclePath(cycleNodes map[string]bool, dependencies map[string][]string)
1820
if len(sortedNodes) > 0 {
1921
startNode = sortedNodes[0]
2022
} else {
23+
importLog.Print("No cycle nodes found, cannot determine cycle path")
2124
return nil
2225
}
2326

27+
importLog.Printf("Starting DFS cycle detection from node: %s", startNode)
28+
2429
// Use DFS to find a path from startNode back to itself
2530
visited := make(map[string]bool)
2631
path := []string{}
2732
if dfsForCycle(startNode, startNode, cycleNodes, dependencies, visited, &path, true) {
33+
importLog.Printf("Cycle path found: %v", path)
2834
return path
2935
}
3036

37+
importLog.Print("DFS completed but no cycle path could be constructed")
3138
return nil
3239
}
3340

@@ -53,6 +60,7 @@ func dfsForCycle(current, target string, cycleNodes map[string]bool, dependencie
5360
for _, dep := range sortedDeps {
5461
// Found the cycle - we've reached the target again
5562
if !isFirst && dep == target {
63+
importLog.Printf("Cycle back-edge found: %s -> %s", current, dep)
5664
*path = append(*path, dep) // Add the back-edge
5765
return true
5866
}

pkg/parser/schedule_cron_detection.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ func IsDailyCron(cron string) bool {
3737
}
3838
}
3939

40-
return fields[2] == "*" && fields[3] == "*" && fields[4] == "*"
40+
result := fields[2] == "*" && fields[3] == "*" && fields[4] == "*"
41+
if result {
42+
log.Printf("Cron expression classified as daily: %q (minute=%s, hour=%s)", cron, minute, hour)
43+
}
44+
return result
4145
}
4246

4347
// IsHourlyCron checks if a cron expression represents an hourly interval with a fixed minute
@@ -67,7 +71,11 @@ func IsHourlyCron(cron string) bool {
6771
}
6872

6973
// Check remaining fields are wildcards
70-
return fields[2] == "*" && fields[3] == "*" && fields[4] == "*"
74+
result := fields[2] == "*" && fields[3] == "*" && fields[4] == "*"
75+
if result {
76+
log.Printf("Cron expression classified as hourly: %q (minute=%s, hour=%s)", cron, minute, hour)
77+
}
78+
return result
7179
}
7280

7381
// IsWeeklyCron checks if a cron expression represents a weekly schedule at a fixed time
@@ -125,6 +133,7 @@ func IsCronExpression(input string) bool {
125133
// A cron expression has exactly 5 fields
126134
fields := strings.Fields(input)
127135
if len(fields) != 5 {
136+
log.Printf("Input is not a cron expression (expected 5 fields, got %d): %q", len(fields), input)
128137
return false
129138
}
130139

pkg/parser/schema_compiler.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,18 +137,23 @@ func GetSafeOutputTypeKeys() ([]string, error) {
137137
}
138138

139139
func validateWithSchema(frontmatter map[string]any, schemaJSON, context string) error {
140+
schemaCompilerLog.Printf("Validating frontmatter against schema for context: %s (%d fields)", context, len(frontmatter))
141+
140142
// Determine which cached schema to use based on the schemaJSON
141143
var schema *jsonschema.Schema
142144
var err error
143145

144146
switch schemaJSON {
145147
case mainWorkflowSchema:
148+
schemaCompilerLog.Print("Using cached main workflow schema")
146149
schema, err = getCompiledMainWorkflowSchema()
147150
case mcpConfigSchema:
151+
schemaCompilerLog.Print("Using cached MCP config schema")
148152
schema, err = getCompiledMcpConfigSchema()
149153
default:
150154
// Fallback for unknown schemas (shouldn't happen in normal operation)
151155
// Compile the schema on-the-fly
156+
schemaCompilerLog.Print("Compiling unknown schema on-the-fly")
152157
schema, err = compileSchema(schemaJSON, "http://contoso.com/schema.json")
153158
}
154159

@@ -177,9 +182,11 @@ func validateWithSchema(frontmatter map[string]any, schemaJSON, context string)
177182

178183
// Validate the normalized frontmatter
179184
if err := schema.Validate(normalizedFrontmatter); err != nil {
185+
schemaCompilerLog.Printf("Schema validation failed for %s: %v", context, err)
180186
return err
181187
}
182188

189+
schemaCompilerLog.Printf("Schema validation passed for context: %s", context)
183190
return nil
184191
}
185192

pkg/workflow/codex_mcp.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,13 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an
164164
// renderCodexMCPConfigWithContext generates custom MCP server configuration for a single tool in codex workflow config.toml
165165
// This version includes workflowData to determine if localhost URLs should be rewritten
166166
func (e *CodexEngine) renderCodexMCPConfigWithContext(yaml *strings.Builder, toolName string, toolConfig map[string]any, workflowData *WorkflowData) error {
167-
yaml.WriteString(" \n")
168-
fmt.Fprintf(yaml, " [mcp_servers.%s]\n", toolName)
169-
170167
// Determine if localhost URLs should be rewritten to host.docker.internal
171168
// This is needed when firewall is enabled (agent is not disabled)
172169
rewriteLocalhost := shouldRewriteLocalhostToDocker(workflowData)
170+
codexMCPLog.Printf("Rendering TOML MCP config for custom tool: %s (rewrite_localhost=%v)", toolName, rewriteLocalhost)
171+
172+
yaml.WriteString(" \n")
173+
fmt.Fprintf(yaml, " [mcp_servers.%s]\n", toolName)
173174

174175
// Use the shared MCP config renderer with TOML format
175176
renderer := MCPConfigRenderer{
@@ -180,6 +181,7 @@ func (e *CodexEngine) renderCodexMCPConfigWithContext(yaml *strings.Builder, too
180181

181182
err := renderSharedMCPConfig(yaml, toolName, toolConfig, renderer)
182183
if err != nil {
184+
codexMCPLog.Printf("Failed to render TOML MCP config for tool %s: %v", toolName, err)
183185
return err
184186
}
185187

@@ -191,6 +193,7 @@ func (e *CodexEngine) renderCodexMCPConfigWithContext(yaml *strings.Builder, too
191193
func (e *CodexEngine) renderCodexJSONMCPConfigWithContext(yaml *strings.Builder, toolName string, toolConfig map[string]any, isLast bool, workflowData *WorkflowData) error {
192194
// Determine if localhost URLs should be rewritten to host.docker.internal
193195
rewriteLocalhost := shouldRewriteLocalhostToDocker(workflowData)
196+
codexMCPLog.Printf("Rendering JSON MCP config for gateway tool: %s (isLast=%v, rewrite_localhost=%v)", toolName, isLast, rewriteLocalhost)
194197

195198
// Use the shared renderer with JSON format for gateway
196199
renderer := MCPConfigRenderer{
@@ -203,6 +206,7 @@ func (e *CodexEngine) renderCodexJSONMCPConfigWithContext(yaml *strings.Builder,
203206

204207
err := renderSharedMCPConfig(yaml, toolName, toolConfig, renderer)
205208
if err != nil {
209+
codexMCPLog.Printf("Failed to render JSON MCP config for tool %s: %v", toolName, err)
206210
return err
207211
}
208212

0 commit comments

Comments
 (0)