
If you want to send data from NodeJS application to Log Analytics/Sentinel you can do it by using the HTTP Log Collector API.

Note: If your app is in Azure PaaS solution, you should check out AppInsights first before going to this route 🙂
Writing module for the Log Collector API
There we’re some existing examples to do this, but I couldn’t get them to work in quick breeze. Due to this I did my own implementation with some key differences:
Signature generation part is done in two phases to improve readability
- Basically I separated the creation of buffer shared key to base64 into an separate variable (var)
Function is bit different with callbacks and try catch logic added
Request Module will handle the Body Payload as non stringified
I did find, that If I sent the body payload stringified, it wouldnt match with the signature. To get the signature to match with the body payload, I added the request option json:true, and sent the non-stringified JSON payload.
The module to be imported
//https://nodejs.org/api/crypto.html
//https://docs.microsoft.com/en-us/azure/azure-monitor/platform/data-collector-api
//https://stackoverflow.com/questions/44532530/encoding-encrypting-the-azure-log-analytics-authorization-header-in-node-js
const rq = require('request')
const crypto = require('crypto')
const util = require('util')
function PushToAzureLogs (content,{id,key,rfc1123date,LogType}, callback) {
console.log(id)
try {
//Checking if the data can be parsed as JSON
if ( JSON.parse(JSON.stringify(content)) ) {
var length = Buffer.byteLength(JSON.stringify(content),'utf8')
var binaryKey = Buffer.from(key,'base64')
var stringToSign = 'POST\n' + length + '\napplication/json\nx-ms-date:' + rfc1123date + '\n/api/logs';
//console.log(stringToSign)
var hash = crypto.createHmac('sha256',binaryKey)
.update(stringToSign,'utf8')
.digest('base64')
var authorization = "SharedKey "+id +":"+hash
var options= {
json:true,
headers:{
"content-type": "application/json",
"authorization":authorization,
"Log-Type":LogType,
"x-ms-date":rfc1123date,
"time-generated-field":"DateValue"
},
body:content
}
var uri = "https://"+ id + ".ods.opinsights.azure.com/api/logs?api-version=2016-04-01"
rq.post(uri,options,(err,Response) => {
//return if error inside try catch block
if (err) {
return callback(("Not data sent to LA: " + err))
}
callback(("Data sent to LA " +util.inspect(content) + "with status code " + Response.statusCode))
})
}
//Catch error if data cant be parsed as JSON
} catch (err) {
callback(("Not data sent to LA: " + err))
}
}
module.exports={PushToAzureLogs}
Example from ExpressJS
//Add your other dependencies before this
const logs = require('./SRC/laws')
//define workspace details
const laws = {
id:'yourID',
key:'yourKey',
rfc1123date:(new Date).toUTCString(),
LogType:'yourLogType'
}
app.get('/graph', (request,response) => {
//not related to LA, this the data I am sending to LA
var token = mods.readToken('rt').access_token
mods.apiCall(token,'https://graph.microsoft.com/v1.0/me?$select=displayName,givenName,onPremisesSamAccountName', (data) => {
console.log('reading graph', data)
//LA object
jsonObject = {
WAFCaller:request.hostname,
identity:data.displayName,
datasource:request.ip
}
console.log(jsonObject)
//send data to LA
logs.PushToAzureLogs(jsonObject,laws,(data)=> {
console.log(data)
})
//return original response
response.send(data)
})
})
Once the data is sent, it will take about 5-10 minutes, for the first entries to be popping up


If /when you attach the Log Analytics workspace to Sentinel, you can then use it create your own hunting queries, and combine the data you have with TI-feeds etc

Happy hunting!
0 comments on “NodeJS Logging integration with Azure Log Analytics/Sentinel”