Log to ULS using javascript
By Anatoly Mironov
The more javascript code is produced in SharePoint solutions, the more need we have to log information and possible errors to a central logging place in SharePoint: ULS. This blog post is about logging to ULS from javascript. For a while ago I read a blog post:
The author @avishnyakov mentions the ability log to ULS from javascript. I want to dive deeper. [sourcecode language=“javascript”] ULS.enable = true ULSOnError(“Hello from javascript”, location.href, 0); [/sourcecode] What this function actually does, is that it calls a web service called _vti_bin/diagnostics.asmx
We can follow the function in the init.debug.js [sourcecode language=“javascript”] function ULSOnError(msg, url, line) { return ULSSendExceptionImpl(msg, url, line, ULSOnError.caller); } [/sourcecode] ULSOnError invokes ULSSendExceptionImpl: [sourcecode language=“javascript”] function ULSSendExceptionImpl(msg, url, line, oCaller) { if (Boolean(ULS) && ULS.enable) { ULS.enable = false; window.onerror = ULS.OriginalOnError; ULS.WebServiceNS = “http://schemas.microsoft.com/sharepoint/diagnostics/"; try { ULS.message = msg; if (url.indexOf(’?’) != -1) url = url.substr(0, url.indexOf(’?’)); ULS.file = url.substr(url.lastIndexOf(’/’) + 1); ULS.line = line; ULS.teamName = “”; ULS.originalFile = “”; ULS.callStack = ‘\n’ + ULSGetCallstack(oCaller) + ‘’; ULS.clientInfo = ‘\n’ + ULSGetClientInfo() + ‘’; ULSSendReport(true); } catch (e) { } } if (Boolean(ULS) && Boolean(ULS.OriginalOnError)) return ULS.OriginalOnError(msg, url, String(line)); else return false; } [/sourcecode] ULSSendExceptionImpl invokes ULSSendReport: [sourcecode language=“javascript”] function ULSSendReport(async) { ULS.request = new XMLHttpRequest(); ULS.request.onreadystatechange = ULSHandleWebServiceResponse; ULS.request.open(“POST”, ULSGetWebServiceUrl(), async); ULS.request.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”); ULS.request.setRequestHeader(“SOAPAction”, ULS.WebServiceNS + “SendClientScriptErrorReport”); ULS.request.send(’’ + ‘<soap:Envelope xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=“http://www.w3.org/2001/XMLSchema" xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/">' + ‘soap:Body’ + ‘’ + ‘’ + ULSEncodeXML(ULS.message) + ‘’ + ‘’ + ULSEncodeXML(ULS.file) + ‘’ + ‘’ + String(ULS.line) + ‘’ + ‘’ + ULSEncodeXML(ULS.callStack) + ‘’ + ‘’ + ULSEncodeXML(ULS.clientInfo) + ‘’ + ‘’ + ULSEncodeXML(ULS.teamName) + ‘’ + ‘’ + ULSEncodeXML(ULS.originalFile) + ‘’ + ‘’ + ‘</soap:Body>’ + ‘</soap:Envelope>’); } [/sourcecode]
Alternatives
An alternative way is to create an own handler that is invoked through an ajax request and that implement an own logic for writing logs to ULS. You can see a neat solution provided by Albert Jan-Shot:
Not to be confused with SP.ULS.log
There is another utility function for logging: SP.ULS.log, this function logs messages in a new browser window. In my opinion, it is a substitute for console.log, but the good thing is that you have to manually enable it in order to see:
Logging from an app
If you are developing a sharepoint app, you can log app errors easily by using: [code language=“javascript”] SP.Utilities.Utility.logCustomAppError( SP.ClientContext.get_current(), errorMessage); [/code]