@@ -3,7 +3,7 @@ package diagnostics
33import (
44 "encoding/json"
55 "fmt"
6- "log"
6+ "log/slog "
77 "os"
88 "strings"
99 "time"
@@ -56,18 +56,61 @@ type diagnostic struct {
5656var diagnosticsEmitted , diagnosticsLimit uint = 0 , 100
5757var noDiagnosticDirPrinted bool = false
5858
59- func emitDiagnostic ( sourceid , sourcename , markdownMessage string , severity diagnosticSeverity , visibility * visibilityStruct , location * locationStruct ) {
60- if diagnosticsEmitted < diagnosticsLimit {
61- diagnosticsEmitted += 1
59+ type DiagnosticsWriter interface {
60+ WriteDiagnostic ( d diagnostic )
61+ }
6262
63- diagnosticDir := os .Getenv ("CODEQL_EXTRACTOR_GO_DIAGNOSTIC_DIR" )
64- if diagnosticDir == "" {
65- if ! noDiagnosticDirPrinted {
66- log .Println ("No diagnostic directory set, so not emitting diagnostic" )
67- noDiagnosticDirPrinted = true
68- }
69- return
63+ type FileDiagnosticsWriter struct {
64+ diagnosticDir string
65+ }
66+
67+ func (writer * FileDiagnosticsWriter ) WriteDiagnostic (d diagnostic ) {
68+ content , err := json .Marshal (d )
69+ if err != nil {
70+ slog .Error ("Failed to encode diagnostic as JSON" , slog .Any ("err" , err ))
71+ return
72+ }
73+
74+ targetFile , err := os .CreateTemp (writer .diagnosticDir , "go-extractor.*.json" )
75+ if err != nil {
76+ slog .Error ("Failed to create diagnostic file" , slog .Any ("err" , err ))
77+ return
78+ }
79+ defer func () {
80+ if err := targetFile .Close (); err != nil {
81+ slog .Error ("Failed to close diagnostic file" , slog .Any ("err" , err ))
82+ }
83+ }()
84+
85+ _ , err = targetFile .Write (content )
86+ if err != nil {
87+ slog .Error ("Failed to write to diagnostic file" , slog .Any ("err" , err ))
88+ }
89+ }
90+
91+ var DefaultWriter * FileDiagnosticsWriter = nil
92+
93+ func NewFileDiagnosticsWriter () * FileDiagnosticsWriter {
94+ diagnosticDir := os .Getenv ("CODEQL_EXTRACTOR_GO_DIAGNOSTIC_DIR" )
95+ if diagnosticDir == "" {
96+ if ! noDiagnosticDirPrinted {
97+ slog .Warn ("No diagnostic directory set, so not emitting diagnostics" )
98+ noDiagnosticDirPrinted = true
7099 }
100+ return nil
101+ }
102+
103+ return & FileDiagnosticsWriter {diagnosticDir }
104+ }
105+
106+ func init () {
107+ DefaultWriter = NewFileDiagnosticsWriter ()
108+ }
109+
110+ // Emits a diagnostic using the specified `DiagnosticsWriter`.
111+ func emitDiagnosticTo (writer DiagnosticsWriter , sourceid , sourcename , markdownMessage string , severity diagnosticSeverity , visibility * visibilityStruct , location * locationStruct ) {
112+ if diagnosticsEmitted < diagnosticsLimit {
113+ diagnosticsEmitted += 1
71114
72115 timestamp := time .Now ().UTC ().Format ("2006-01-02T15:04:05.000" ) + "Z"
73116
@@ -93,31 +136,16 @@ func emitDiagnostic(sourceid, sourcename, markdownMessage string, severity diagn
93136 }
94137 }
95138
96- content , err := json .Marshal (d )
97- if err != nil {
98- log .Println (err )
99- return
100- }
101-
102- targetFile , err := os .CreateTemp (diagnosticDir , "go-extractor.*.json" )
103- if err != nil {
104- log .Println ("Failed to create diagnostic file: " )
105- log .Println (err )
106- return
107- }
108- defer func () {
109- if err := targetFile .Close (); err != nil {
110- log .Println ("Failed to close diagnostic file:" )
111- log .Println (err )
112- }
113- }()
139+ writer .WriteDiagnostic (d )
140+ }
141+ }
114142
115- _ , err = targetFile .Write (content )
116- if err != nil {
117- log .Println ("Failed to write to diagnostic file: " )
118- log .Println (err )
119- }
143+ // Emits a diagnostic using the default `DiagnosticsWriter`.
144+ func emitDiagnostic (sourceid , sourcename , markdownMessage string , severity diagnosticSeverity , visibility * visibilityStruct , location * locationStruct ) {
145+ if DefaultWriter == nil {
146+ return
120147 }
148+ emitDiagnosticTo (DefaultWriter , sourceid , sourcename , markdownMessage , severity , visibility , location )
121149}
122150
123151func EmitPackageDifferentOSArchitecture (pkgPath string ) {
0 commit comments