Skip to content

Instantly share code, notes, and snippets.

@tylerpeterson
Created June 17, 2020 23:28
Show Gist options
  • Save tylerpeterson/338f9ddb4fd676ce97513abbf8ac412b to your computer and use it in GitHub Desktop.
Save tylerpeterson/338f9ddb4fd676ce97513abbf8ac412b to your computer and use it in GitHub Desktop.
Turning interactive Splunk results with Agent strings into a nice CSV file
#!/usr/bin/env node
// https://stackoverflow.com/questions/45854169/how-can-i-use-an-es6-import-in-node
// That's why this package.json says where in a module
// Use Bowser to interpret the agent strings
// Seems to give results comparable to https://developers.whatismybrowser.com/useragents/parse/#parse-useragent
// https://www.npmjs.com/package/bowser
// https://lancedikson.github.io/bowser/docs/
import Bowser from "bowser"
import fs from "fs"
import readline from "readline"
/* Data is in a file exported "as json" from Splunk. But that just means each row is JSON, not the whole file.
* This was the query to get the data:
*
index=frontier user_agent path=/tree/merge*
| join request_id
[search index=frontier fs_host=fs-tree-v7-prod path!=/version status=200 ] | rex field=path (?<parsedpath>^\/\w+\/\w+\/)| search parsedpath="/tree/merge/"
| top limit=20 user_agent
https://familysearch.splunkcloud.com/en-US/app/fs-familytree/search?q=search%20index%3Dfrontier%20user_agent%20path%3D%2Ftree%2Fmerge*%0A%7C%20%20join%20request_id%0A%20%20%20%20%5Bsearch%20index%3Dfrontier%20fs_host%3Dfs-tree-v7-prod%20path!%3D%2Fversion%20status%3D200%20%5D%20%20%7C%20rex%20field%3Dpath%20(%3F%3Cparsedpath%3E%5E%5C%2F%5Cw%2B%5C%2F%5Cw%2B%5C%2F)%7C%20search%20parsedpath%3D%22%2Ftree%2Fmerge%2F%22%20%0A%7C%20top%20limit%3D20%20user_agent&display.page.search.mode=verbose&dispatch.sample_ratio=1&earliest=-6d%40d&latest=now&display.page.search.tab=statistics&display.general.type=statistics&sid=1592434367.129354_6CFC0A40-ECE0-448E-A055-B34B0058D3B5
I used JOIN in that search: https://docs.splunk.com/Documentation/Splunk/8.0.4/SearchReference/Join
*
* */
const fields = [
'Browser',
'Version',
'OS',
'platform',
'count',
'percent'
]
console.log('"' + fields.join('","') + '"')
async function processLines() {
const stream = fs.createReadStream('input.json')
const rl = readline.createInterface({
input: stream,
crlfDelay: Infinity
})
// https://stackoverflow.com/questions/20086849/how-to-read-from-stdin-line-by-line-in-node
// https://stackoverflow.com/questions/6156501/read-a-file-one-line-at-a-time-in-node-js
for await (const line of rl) {
const lineData = JSON.parse(line).result
const agent = Bowser.parse(lineData.user_agent)
//console.log(agent)
const osName = agent.os.name + (agent.os.versionName ? " " + agent.os.versionName : (agent.os.version ? ` (${agent.os.version})` : ''))
console.log(`"${agent.browser.name}","${agent.browser.version}","${osName}","${agent.platform.type}",${lineData.count},${lineData.percent}`)
}
}
processLines()
{
"name": "agent-to-browser",
"version": "1.0.0",
"type": "module",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Tyler Peterson <[email protected]>",
"license": "MIT",
"dependencies": {
"bowser": "^2.9.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment