@@ -33,6 +33,36 @@ enum class Severity(val sev: Int) {
3333 ErrorGlobal (8 )
3434}
3535
36+ class LogMessage (private val kind : String , private val message : String ) {
37+ val timestamp: String
38+ init {
39+ timestamp = " ${SimpleDateFormat (" yyyy-MM-dd HH:mm:ss" ).format(Date ())} "
40+ }
41+
42+ fun toText (): String {
43+ return " [$timestamp K] [$kind ] $message "
44+ }
45+
46+ private fun escape (str : String ): String {
47+ return str.replace(" \\ " , " \\\\ " )
48+ .replace(" \" " , " \\\" " )
49+ .replace(" /" , " \\ /" )
50+ .replace(" \b " , " \\ b" )
51+ .replace(" \u000C " , " \\ f" )
52+ .replace(" \n " , " \\ n" )
53+ .replace(" \r " , " \\ r" )
54+ .replace(" \t " , " \\ t" )
55+ }
56+
57+ fun toJsonLine (): String {
58+ val kvs = listOf (Pair (" origin" , " CodeQL Kotlin extractor" ),
59+ Pair (" timestamp" , timestamp),
60+ Pair (" kind" , kind),
61+ Pair (" message" , message))
62+ return " { " + kvs.map { p -> " \" ${p.first} \" : \" ${escape(p.second)} \" " }.joinToString(" , " ) + " }\n "
63+ }
64+ }
65+
3666data class ExtractorContext (val kind : String , val element : IrElement , val name : String , val loc : String )
3767
3868open class LoggerBase (val logCounter : LogCounter ) {
@@ -54,10 +84,6 @@ open class LoggerBase(val logCounter: LogCounter) {
5484 }
5585 }
5686
57- private fun timestamp (): String {
58- return " [${SimpleDateFormat (" yyyy-MM-dd HH:mm:ss" ).format(Date ())} K]"
59- }
60-
6187 private fun getDiagnosticLocation (): String? {
6288 val st = Exception ().stackTrace
6389 for (x in st) {
@@ -84,7 +110,6 @@ open class LoggerBase(val logCounter: LogCounter) {
84110 fun diagnostic (tw : TrapWriter , severity : Severity , msg : String , extraInfo : String? , locationString : String? = null, mkLocationId : () -> Label <DbLocation > = { tw.unknownLocation }) {
85111 val diagnosticLoc = getDiagnosticLocation()
86112 val diagnosticLocStr = if (diagnosticLoc == null ) " <unknown location>" else diagnosticLoc
87- val extraInfoStr = if (extraInfo == null ) " " else (extraInfo + " \n " )
88113 val suffix =
89114 if (diagnosticLoc == null ) {
90115 " Missing caller information.\n "
@@ -100,8 +125,10 @@ open class LoggerBase(val logCounter: LogCounter) {
100125 }
101126 val fullMsgBuilder = StringBuilder ()
102127 fullMsgBuilder.append(msg)
103- fullMsgBuilder.append(' \n ' )
104- fullMsgBuilder.append(extraInfoStr)
128+ if (extraInfo != null ) {
129+ fullMsgBuilder.append(' \n ' )
130+ fullMsgBuilder.append(extraInfo)
131+ }
105132
106133 val iter = extractorContextStack.listIterator(extractorContextStack.size)
107134 while (iter.hasPrevious()) {
@@ -111,38 +138,38 @@ open class LoggerBase(val logCounter: LogCounter) {
111138 fullMsgBuilder.append(suffix)
112139
113140 val fullMsg = fullMsgBuilder.toString()
114- val ts = timestamp()
141+ val locStr = if (locationString == null ) " " else " At " + locationString + " : "
142+ val kind = if (severity <= Severity .WarnHigh ) " WARN" else " ERROR"
143+ val logMessage = LogMessage (kind, " Diagnostic($diagnosticLocStr ): $locStr$fullMsg " )
115144 // We don't actually make the location until after the `return` above
116145 val locationId = mkLocationId()
117146 val diagLabel = tw.getFreshIdLabel<DbDiagnostic >()
118- tw.writeDiagnostics(diagLabel, " CodeQL Kotlin extractor" , severity.sev, " " , msg, " $ts $fullMsg " , locationId)
147+ tw.writeDiagnostics(diagLabel, " CodeQL Kotlin extractor" , severity.sev, " " , msg, " ${logMessage.timestamp} $fullMsg " , locationId)
119148 tw.writeDiagnostic_for(diagLabel, StringLabel (" compilation" ), file_number, file_number_diagnostic_number++ )
120- val locStr = if (locationString == null ) " " else " At " + locationString + " : "
121- val kind = if (severity <= Severity .WarnHigh ) " WARN" else " ERROR"
122- logStream.write(" $ts [$kind ] Diagnostic($diagnosticLocStr ): $locStr$fullMsg " )
149+ logStream.write(logMessage.toJsonLine())
123150 }
124151
125152 fun trace (tw : TrapWriter , msg : String ) {
126153 if (verbosity >= 4 ) {
127- val fullMsg = " ${timestamp()} [ TRACE] $ msg"
128- tw.writeComment(fullMsg )
129- logStream.write(fullMsg + " \n " )
154+ val logMessage = LogMessage ( " TRACE" , msg)
155+ tw.writeComment(logMessage.toText() )
156+ logStream.write(logMessage.toJsonLine() )
130157 }
131158 }
132159
133160 fun debug (tw : TrapWriter , msg : String ) {
134161 if (verbosity >= 4 ) {
135- val fullMsg = " ${timestamp()} [ DEBUG] $ msg"
136- tw.writeComment(fullMsg )
137- logStream.write(fullMsg + " \n " )
162+ val logMessage = LogMessage ( " DEBUG" , msg)
163+ tw.writeComment(logMessage.toText() )
164+ logStream.write(logMessage.toJsonLine() )
138165 }
139166 }
140167
141168 fun info (tw : TrapWriter , msg : String ) {
142169 if (verbosity >= 3 ) {
143- val fullMsg = " ${timestamp()} [ INFO] $ msg"
144- tw.writeComment(fullMsg )
145- logStream.write(fullMsg + " \n " )
170+ val logMessage = LogMessage ( " INFO" , msg)
171+ tw.writeComment(logMessage.toText() )
172+ logStream.write(logMessage.toJsonLine() )
146173 }
147174 }
148175
@@ -160,9 +187,12 @@ open class LoggerBase(val logCounter: LogCounter) {
160187 fun printLimitedDiagnosticCounts (tw : TrapWriter ) {
161188 for ((caller, count) in logCounter.diagnosticCounts) {
162189 if (count >= logCounter.diagnosticLimit) {
163- val msg = " Total of $count diagnostics from $caller .\n "
164- tw.writeComment(msg)
165- logStream.write(msg)
190+ // We don't know if this location relates to an error
191+ // or a warning, so we just declare hitting the limit
192+ // to be an error regardless.
193+ val logMessage = LogMessage (" ERROR" , " Total of $count diagnostics from $caller ." )
194+ tw.writeComment(logMessage.toText())
195+ logStream.write(logMessage.toJsonLine())
166196 }
167197 }
168198 }
0 commit comments