Skip to content

Commit 729563c

Browse files
committed
QL: Add preliminary support for structured logs
1 parent cf73491 commit 729563c

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
private import ql
2+
private import codeql_ql.ast.internal.TreeSitter
3+
4+
class Object extends JSON::Object {
5+
JSON::Value getValue(string key) {
6+
exists(JSON::Pair p |
7+
p = this.getChild(_) and p.getKey().(JSON::String).getChild().getValue() = key
8+
|
9+
result = p.getValue()
10+
)
11+
}
12+
13+
string getString(string key) { result = this.getValue(key).(JSON::String).getChild().getValue() }
14+
15+
int getNumber(string key) { result = this.getValue(key).(JSON::Number).getValue().toInt() }
16+
17+
Array getArray(string key) { result = this.getValue(key) }
18+
19+
string getType() { result = this.getString("type") }
20+
21+
int getEventId() { result = this.getNumber("event_id") }
22+
23+
string getTime() { result = this.getString("time") }
24+
}
25+
26+
class Array extends JSON::Array {
27+
Object getObject(int i) { result = this.getChild(i) }
28+
29+
string getString(int i) { result = this.getChild(i).(JSON::String).getChild().getValue() }
30+
31+
int getNumber(int i) { result = this.getChild(i).(JSON::Number).getValue().toInt() }
32+
}
33+
34+
abstract class LogEntry extends Object { }
35+
36+
class LogHeader extends LogEntry {
37+
LogHeader() { this.getType() = "LOG_HEADER" }
38+
39+
string getCodeQLVersion() { result = this.getString("codeqlVersion") }
40+
41+
string getLogVersion() { result = this.getString("logVersion") }
42+
}
43+
44+
class QueryStarted extends LogEntry {
45+
QueryStarted() { this.getType() = "QUERY_STARTED" }
46+
47+
string getQueryName() { result = this.getString("queryName") }
48+
49+
int getStage(int i) { result = this.getArray("stage").getNumber(i) }
50+
}
51+
52+
class PredicateStarted extends LogEntry {
53+
PredicateStarted() { this.getType() = "PREDICATE_STARTED" }
54+
55+
string getPredicateName() { result = this.getString("predicateName") }
56+
57+
string getPosition() { result = this.getString("position") }
58+
59+
string getPredicateType() { result = this.getString("predicateType") }
60+
61+
int getQueryCausingWork() { result = this.getNumber("queryCausingWork") }
62+
63+
string getRAHash() { result = this.getString("raHash") }
64+
65+
Object getRA() { result = this.getValue("ra") }
66+
}
67+
68+
class PipelineStarted extends LogEntry {
69+
PipelineStarted() { this.getType() = "PIPELINE_STARTED" }
70+
71+
int getPredicateStartEvent() { result = this.getNumber("predicateStartEvent") }
72+
73+
string getRAReference() { result = this.getString("raReference") }
74+
}
75+
76+
class PipelineCompleted extends LogEntry {
77+
PipelineCompleted() { this.getType() = "PIPELINE_COMPLETED" }
78+
79+
int getStartEvent() { result = this.getNumber("startEvent") }
80+
81+
string getRAReference() { result = this.getString("raReference") }
82+
83+
int getCount(int i) { result = this.getArray("counts").getNumber(i) }
84+
85+
int getDuplicationPercentage(int i) {
86+
result = this.getArray("duplicationPercentages").getNumber(i)
87+
}
88+
89+
int getResultSize() { result = this.getNumber("resultSize") }
90+
}
91+
92+
class PredicateCompleted extends LogEntry {
93+
PredicateCompleted() { this.getType() = "PREDICATE_COMPLETED" }
94+
95+
int getStartEvent() { result = this.getNumber("startEvent") }
96+
97+
int getResultSize() { result = this.getNumber("resultSize") }
98+
}
99+
100+
class QueryCompleted extends LogEntry {
101+
QueryCompleted() { this.getType() = "QUERY_COMPLETED" }
102+
103+
int getStartEvent() { result = this.getNumber("startEvent") }
104+
105+
string getTerminationType() { result = this.getString("terminationType") }
106+
}
107+
108+
class LogFooter extends LogEntry {
109+
LogFooter() { this.getType() = "LOG_FOOTER" }
110+
}
111+
112+
class CacheLookup extends LogEntry {
113+
CacheLookup() { this.getType() = "CACHE_LOOKUP" }
114+
115+
int getRelationSize() { result = this.getNumber("relationSize") }
116+
}
117+
118+
class SentinelEmpty extends LogEntry {
119+
SentinelEmpty() { this.getType() = "SENTINEL_EMPTY" }
120+
}
121+
122+
// Stuff to test whether we've covered all event types
123+
private File logFile() { result = any(LogHeader h).getLocation().getFile() }
124+
125+
private Object missing() {
126+
result =
127+
any(Object o |
128+
o.getLocation().getFile() = logFile() and
129+
not o instanceof LogEntry and
130+
not exists(o.getParent().getParent()) // don't count nested objects
131+
)
132+
}

0 commit comments

Comments
 (0)