Last active
March 31, 2016 18:04
-
-
Save eduard93/3af3e1f31604fef81df6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2015.1.1 (Build 505U)" ts="2015-06-17 22:55:48"> | |
<Class name="App.Log"> | |
<Super>%Persistent</Super> | |
<TimeChanged>63720,82487.41709</TimeChanged> | |
<TimeCreated>63685,63064.148177</TimeCreated> | |
<Parameter name="Null"> | |
<Description> | |
Replacement for missing values</Description> | |
<Default>Null</Default> | |
</Parameter> | |
<Property name="EventType"> | |
<Description> | |
Type of event</Description> | |
<Type>%String</Type> | |
<InitialExpression>"INFO"</InitialExpression> | |
<Parameter name="MAXLEN" value="10"/> | |
<Parameter name="VALUELIST" value=",NONE,FATAL,ERROR,WARN,INFO,STAT,DEBUG,RAW"/> | |
</Property> | |
<Property name="ClassName"> | |
<Description> | |
Name of class, where event happened</Description> | |
<Type>%String</Type> | |
<Parameter name="MAXLEN" value="256"/> | |
</Property> | |
<Property name="MethodName"> | |
<Description> | |
Name of method, where event happened</Description> | |
<Type>%String</Type> | |
<Parameter name="MAXLEN" value="128"/> | |
</Property> | |
<Property name="Source"> | |
<Description> | |
Line of int code</Description> | |
<Type>%String</Type> | |
<Parameter name="MAXLEN" value="2000"/> | |
</Property> | |
<Property name="UserName"> | |
<Description> | |
Cache user</Description> | |
<Type>%String</Type> | |
<InitialExpression>$username</InitialExpression> | |
<Parameter name="MAXLEN" value="128"/> | |
</Property> | |
<Property name="Arguments"> | |
<Description> | |
Arguments' values passed to method</Description> | |
<Type>%String</Type> | |
<Parameter name="MAXLEN" value="32000"/> | |
<Parameter name="TRUNCATE" value="1"/> | |
</Property> | |
<Property name="TimeStamp"> | |
<Description> | |
Date and time</Description> | |
<Type>%TimeStamp</Type> | |
<InitialExpression>$zdt($h, 3, 1)</InitialExpression> | |
</Property> | |
<Property name="Message"> | |
<Description> | |
User message</Description> | |
<Type>%String</Type> | |
<Parameter name="MAXLEN" value="32000"/> | |
<Parameter name="TRUNCATE" value="1"/> | |
</Property> | |
<Property name="ClientIPAddress"> | |
<Description> | |
User IP address</Description> | |
<Type>%String</Type> | |
<InitialExpression>..GetClientAddress()</InitialExpression> | |
<Parameter name="MAXLEN" value="32"/> | |
</Property> | |
<Index name="idxEventType"> | |
<Type>bitmap</Type> | |
<Properties>EventType</Properties> | |
</Index> | |
<Index name="idxUserName"> | |
<Type>bitmap</Type> | |
<Properties>UserName</Properties> | |
</Index> | |
<Index name="idxClassName"> | |
<Type>bitmap</Type> | |
<Properties>ClassName</Properties> | |
</Index> | |
<Index name="idxTimeStamp"> | |
<Type>bitslice</Type> | |
<Properties>TimeStamp</Properties> | |
</Index> | |
<Index name="idxClientIPAddress"> | |
<Properties>ClientIPAddress</Properties> | |
</Index> | |
<Method name="GetClientAddress"> | |
<Description> | |
Determine user IP address</Description> | |
<ClassMethod>1</ClassMethod> | |
<Implementation><![CDATA[ | |
// %CSP.Session source is preferable | |
#dim %request As %CSP.Request | |
If ($d(%request)) { | |
Return %request.CgiEnvs("REMOTE_ADDR") | |
} | |
Return $system.Process.ClientIPAddress() | |
]]></Implementation> | |
</Method> | |
<Method name="AddRecord"> | |
<Description> | |
Add new log event | |
Use via $$$LogEventTYPE().</Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>ClassName:%String="",MethodName:%String="",Source:%String="",EventType:%String="",Arguments:%String="",Message:%String=""</FormalSpec> | |
<Implementation><![CDATA[ | |
Set record = ..%New() | |
Set record.Arguments = Arguments | |
Set record.ClassName = ClassName | |
Set record.EventType = EventType | |
Set record.Message = Message | |
Set record.MethodName = MethodName | |
Set record.Source = Source | |
Do record.%Save() | |
]]></Implementation> | |
</Method> | |
<Method name="GetMethodArguments"> | |
<Description> | |
Entry point to get method arguments string </Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>ClassName:%String,MethodName:%String</FormalSpec> | |
<ReturnType>%String</ReturnType> | |
<Implementation><![CDATA[ | |
Set list = ..GetMethodArgumentsList(ClassName,MethodName) | |
Set string = ..ArgumentsListToString(list) | |
Return string | |
]]></Implementation> | |
</Method> | |
<Method name="GetMethodArgumentsList"> | |
<Description> | |
Get a list of method arguments</Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>ClassName:%String,MethodName:%String</FormalSpec> | |
<ReturnType>%List</ReturnType> | |
<Implementation><![CDATA[ | |
Set result = "" | |
Set def = ##class(%Dictionary.CompiledMethod).%OpenId(ClassName _ "||" _ MethodName) | |
If ($IsObject(def)) { | |
Set result = def.FormalSpecParsed | |
} | |
Return result | |
]]></Implementation> | |
</Method> | |
<Method name="ArgumentsListToString"> | |
<Description> | |
Convert list of method arguments to string</Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>List:%List</FormalSpec> | |
<ReturnType>%String</ReturnType> | |
<Implementation><![CDATA[ | |
Set result = "" | |
For i=1:1:$ll(List) { | |
Set result = result _ $$$quote($s(i>1=0:"",1:"; ") _ $lg($lg(List,i))_"=") | |
_ ..GetArgumentValue($lg($lg(List,i)),$lg($lg(List,i),2)) | |
_$S(i=$ll(List)=0:"",1:$$$quote(";")) | |
} | |
Return result | |
]]></Implementation> | |
</Method> | |
<Method name="GetArgumentValue"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>Name:%String,ClassName:%Dictionary.CacheClassname</FormalSpec> | |
<ReturnType>%String</ReturnType> | |
<Implementation><![CDATA[ | |
If $ClassMethod(ClassName, "%Extends", "%RegisteredObject") { | |
// it's an object | |
Return "_##class(App.Log).SerializeObject("_Name _ ")_" | |
} Else { | |
// it's a datatype | |
Return "_$g(" _ Name _ ","_$$$quote(..#Null)_")_" | |
} | |
]]></Implementation> | |
</Method> | |
<Method name="SerializeObject"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>Object</FormalSpec> | |
<ReturnType>%String</ReturnType> | |
<Implementation><![CDATA[ | |
Return:'$IsObject(Object) Object | |
Return ..WriteJSONFromObject(Object) | |
]]></Implementation> | |
</Method> | |
<Method name="WriteJSONFromObject"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>Object</FormalSpec> | |
<ProcedureBlock>0</ProcedureBlock> | |
<ReturnType>%String</ReturnType> | |
<Implementation><![CDATA[ | |
// Create a string that we will redirect to | |
Set Str = "" | |
Use $io::("^"_$ZNAME) | |
// Enable redirection | |
Do ##class(%Device).ReDirectIO(1) | |
// Any write statements here will be redirected to the labels defined below | |
Do ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(Object) | |
// Disable redirection | |
Do ##class(%Device).ReDirectIO(0) | |
Return Str | |
// Labels that allow for IO redirection | |
// Read Character - we don't care about reading | |
rchr(c) Quit | |
// Read a string - we don't care about reading | |
rstr(sz,to) Quit | |
// Write a character - call the output label | |
wchr(s) Do output($char(s)) Quit | |
// Write a form feed - call the output label | |
wff() Do output($char(12)) Quit | |
// Write a newline - call the output label | |
wnl() Do output($char(13,10)) Quit | |
// Write a string - call the output label | |
wstr(s) Do output(s) Quit | |
// Write a tab - call the output label | |
wtab(s) Do output($char(9)) Quit | |
// Output label - this is where you would handle what you actually want to do. | |
// in our case, we want to write to Str | |
output(s) Set Str = Str_s Quit | |
]]></Implementation> | |
</Method> | |
<Method name="LoadContext"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>Id</FormalSpec> | |
<ProcedureBlock>0</ProcedureBlock> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Return:'..%ExistsId(Id) $$$OK | |
Set Obj = ..%OpenId(Id) | |
Set Arguments = Obj.Arguments | |
Set List = ..GetMethodArgumentsList(Obj.ClassName,Obj.MethodName) | |
For i=1:1:$Length(Arguments,";")-1 { | |
Set Argument = $Piece(Arguments,";",i) | |
Set @$lg($lg(List,i)) = ..DeserializeObject($Piece(Argument,"=",2),$lg($lg(List,i),2)) | |
} | |
Kill Obj,Arguments,Argument,i,Id,List | |
]]></Implementation> | |
</Method> | |
<Method name="DeserializeObject"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>String,ClassName</FormalSpec> | |
<ReturnType>%String</ReturnType> | |
<Implementation><![CDATA[ | |
If $ClassMethod(ClassName, "%Extends", "%RegisteredObject") { | |
// it's an object | |
Set st = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(String,,.obj) | |
Return:$$$ISOK(st) obj | |
} | |
Return String | |
]]></Implementation> | |
</Method> | |
<Storage name="Default"> | |
<Type>%Library.CacheStorage</Type> | |
<DataLocation>^App.LogD</DataLocation> | |
<DefaultData>LogDefaultData</DefaultData> | |
<IdLocation>^App.LogD</IdLocation> | |
<IndexLocation>^App.LogI</IndexLocation> | |
<StreamLocation>^App.LogS</StreamLocation> | |
<Data name="LogDefaultData"> | |
<Value name="1"> | |
<Value>%%CLASSNAME</Value> | |
</Value> | |
<Value name="2"> | |
<Value>EventType</Value> | |
</Value> | |
<Value name="3"> | |
<Value>ClassName</Value> | |
</Value> | |
<Value name="4"> | |
<Value>UserName</Value> | |
</Value> | |
<Value name="5"> | |
<Value>MethodName</Value> | |
</Value> | |
<Value name="6"> | |
<Value>Arguments</Value> | |
</Value> | |
<Value name="7"> | |
<Value>TimeStamp</Value> | |
</Value> | |
<Value name="8"> | |
<Value>Message</Value> | |
</Value> | |
<Value name="9"> | |
<Value>ClientIPAddress</Value> | |
</Value> | |
<Value name="10"> | |
<Value>Source</Value> | |
</Value> | |
</Data> | |
</Storage> | |
</Class> | |
<Routine name="App.LogMacro" type="INC" timestamp="63698,56142.070147"><![CDATA[ | |
#define StackPlace $st($st(-1),"PLACE") | |
#define CurrentClass ##Expression($$$quote(%classname)) | |
#define CurrentMethod ##Expression($$$quote(%methodname)) | |
#define MethodArguments ##Expression(##class(App.Log).GetMethodArguments(%classname,%methodname)) | |
#define LogEvent(%type, %message) Do ##class(App.Log).AddRecord($$$CurrentClass,$$$CurrentMethod,$$$StackPlace,%type,$$$MethodArguments,%message) | |
#define LogNone(%message) $$$LogEvent("NONE", %message) | |
#define LogError(%message) $$$LogEvent("ERROR", %message) | |
#define LogFatal(%message) $$$LogEvent("FATAL", %message) | |
#define LogWarn(%message) $$$LogEvent("WARN", %message) | |
#define LogInfo(%message) $$$LogEvent("INFO", %message) | |
#define LogStat(%message) $$$LogEvent("STAT", %message) | |
#define LogDebug(%message) $$$LogEvent("DEBUG", %message) | |
#define LogRaw(%message) $$$LogEvent("RAW", %message) | |
]]></Routine> | |
<Class name="App.Use"> | |
<CompileAfter>App.Log</CompileAfter> | |
<IncludeCode>App.LogMacro</IncludeCode> | |
<TimeChanged>63720,81865.648288</TimeChanged> | |
<TimeCreated>63691,73040.917631</TimeCreated> | |
<Method name="Test"> | |
<Description> | |
do ##class(App.Use).Test()</Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec><![CDATA[a:%Integer=1,&b=2]]></FormalSpec> | |
<Implementation><![CDATA[ $$$LogWarn("User message") // just place this macro in user code you wish to log | |
]]></Implementation> | |
</Method> | |
<Method name="TestWithObjects"> | |
<Description> | |
do ##class(App.Use).TestWithObjects()</Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>a:%Integer=1,b:%ZEN.proxyObject</FormalSpec> | |
<Implementation><![CDATA[ $$$LogWarn("User message") | |
]]></Implementation> | |
</Method> | |
</Class> | |
</Export> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment