Skip to content

Commit e0c419e

Browse files
committed
feat: log all git commands for diagnostic purposes
1 parent 81e6f6a commit e0c419e

File tree

4 files changed

+150
-0
lines changed

4 files changed

+150
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Added "Export System Default Settings" menu item (#544)
1818
- IRIS Business Intelligence items are mapped to the /dfi subdirectory by default (#428)
1919
- Intelligent merge conflict auto-resolution works for the common Business Rule case as well (#391)
20+
- All git commands run on the server, their output, and any associated sync output, are logged to a table for diagnostic purposes (#454)
2021

2122
### Fixed
2223
- Fixed display of other users' username in workspace view on Unix (#530)

cls/SourceControl/Git/Log.cls

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
Class SourceControl.Git.Log Extends %Persistent [ Owner = {%Developer} ]
2+
{
3+
4+
Property TimeStamp As %TimeStamp [ InitialExpression = {$zdt($h,3)} ];
5+
6+
Property Username As %String(MAXLEN = 128) [ InitialExpression = {$Username} ];
7+
8+
Index Username On Username [ Type = bitmap ];
9+
10+
Property LogStream As %Stream.GlobalCharacter;
11+
12+
Property ErrorStream As %Stream.GlobalCharacter;
13+
14+
/// Handy as a property in case this table is mapped
15+
Property Namespace As %String [ InitialExpression = {$Namespace} ];
16+
17+
Index Namespace On Namespace [ Type = bitmap ];
18+
19+
Property Command As %List;
20+
21+
ClassMethod CommandLogicalToDisplay(command As %List) As %String
22+
{
23+
If (command = "") {
24+
Quit ""
25+
}
26+
Quit "git "_$ListToString(command," ")
27+
}
28+
29+
ClassMethod CommandBuildValueArray(command As %List, ByRef valueArray) As %Status
30+
{
31+
Set pointer = 0
32+
While $ListNext(command,pointer,element) {
33+
Set valueArray(element) = ""
34+
}
35+
Quit $$$OK
36+
}
37+
38+
Index CommandElements On Command(KEYS) [ Type = bitmap ];
39+
40+
Property ReturnCode As %Integer;
41+
42+
Property Source As %String [ InitialExpression = {##class(SourceControl.Git.Log).DeriveSource()} ];
43+
44+
Index Source On Source [ Type = bitmap ];
45+
46+
ClassMethod Create(log As %Stream.Object = "", err As %Stream.Object = "", ByRef args, returnCode As %Integer = 0, source As %String = "")
47+
{
48+
Try {
49+
Set inst = ..%New()
50+
If $IsObject($Get(log)) {
51+
Do log.Rewind()
52+
Do inst.LogStream.CopyFromAndSave(log)
53+
Do log.Rewind()
54+
}
55+
If $IsObject($Get(err)) {
56+
Do err.Rewind()
57+
Do inst.ErrorStream.CopyFromAndSave(err)
58+
Do err.Rewind()
59+
}
60+
Set fullCommand = ""
61+
Set key = ""
62+
For {
63+
Set key = $Order(args(key),1,data)
64+
Quit:key=""
65+
Set fullCommand = fullCommand _ $ListBuild(data)
66+
}
67+
Set inst.Command = fullCommand
68+
Set inst.ReturnCode = returnCode
69+
If source '= "" {
70+
Set inst.Source = source
71+
}
72+
$$$ThrowOnError(inst.%Save())
73+
} Catch e {
74+
Do e.Log()
75+
}
76+
}
77+
78+
ClassMethod DeriveSource() As %String
79+
{
80+
Try {
81+
If '$IsObject($Get(%request))#2 {
82+
Return "Studio"
83+
}
84+
If %request.UserAgent [ "Code/" {
85+
Return "VSCode WebView"
86+
} ElseIf (%request.UserAgent [ "node-fetch") {
87+
Return "VSCode API / Menu"
88+
} Else {
89+
Return "Management Portal"
90+
}
91+
} Catch e {
92+
Return "Unknown"
93+
}
94+
}
95+
96+
Storage Default
97+
{
98+
<Data name="LogDefaultData">
99+
<Value name="1">
100+
<Value>%%CLASSNAME</Value>
101+
</Value>
102+
<Value name="2">
103+
<Value>TimeStamp</Value>
104+
</Value>
105+
<Value name="3">
106+
<Value>Username</Value>
107+
</Value>
108+
<Value name="4">
109+
<Value>LogStream</Value>
110+
</Value>
111+
<Value name="5">
112+
<Value>ErrorStream</Value>
113+
</Value>
114+
<Value name="6">
115+
<Value>Namespace</Value>
116+
</Value>
117+
<Value name="7">
118+
<Value>Command</Value>
119+
</Value>
120+
<Value name="8">
121+
<Value>ReturnCode</Value>
122+
</Value>
123+
<Value name="9">
124+
<Value>Source</Value>
125+
</Value>
126+
</Data>
127+
<DataLocation>^SourceControl.Git.LogD</DataLocation>
128+
<DefaultData>LogDefaultData</DefaultData>
129+
<IdLocation>^SourceControl.Git.LogD</IdLocation>
130+
<IndexLocation>^SourceControl.Git.LogI</IndexLocation>
131+
<Property name="%%CLASSNAME"/>
132+
<Property name="%%ID"/>
133+
<Property name="Command"/>
134+
<Property name="ErrorStream"/>
135+
<Property name="LogStream"/>
136+
<Property name="Namespace"/>
137+
<Property name="ReturnCode"/>
138+
<Property name="Source"/>
139+
<Property name="TimeStamp"/>
140+
<Property name="Username"/>
141+
<SQLMap name="IDKEY"/>
142+
<StreamLocation>^SourceControl.Git.LogS</StreamLocation>
143+
<Type>%Storage.Persistent</Type>
144+
}
145+
146+
}
147+

cls/SourceControl/Git/Utils.cls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,7 @@ ClassMethod RunGitCommandWithInput(command As %String, inFile As %String = "", O
19561956
}
19571957
}
19581958
}
1959+
do ##class(SourceControl.Git.Log).Create(outStream,errStream,.newArgs,returnCode)
19591960
quit returnCode
19601961
}
19611962

csp/sync.csp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182

183183
set out = ##class(%Stream.GlobalCharacter).%New()
184184
do buffer.EndCaptureOutput(.out)
185+
do ##class(SourceControl.Git.Log).Create(out,,,,"Sync")
185186
while 'out.AtEnd {
186187
set line = out.ReadLine()
187188
set escapedLine = ..EscapeHTML(line)

0 commit comments

Comments
 (0)