spm-agent-os
Version:
SPM Agent for monitoring operating system metrics
124 lines (123 loc) • 5.19 kB
JavaScript
/*
* @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
*
* @licence Sematext Agent for OS Metrics is free-to-use, proprietary software.
* THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
* This source code may not be copied, reverse engineered, or altered for any purpose.
* This source code is to be used exclusively by users and customers of Sematext.
* Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
*/
var SpmAgent = require('spm-agent')
var Agent = SpmAgent.Agent
var config = SpmAgent.Config
var os = require('os')
var cluster = require('cluster')
var diskfree = require('node-df')
var logger = SpmAgent.Logger
/**
* This module generates OS Metrics. Names are compatible with collectd. SpmSender uses collectd format
* @returns {Agent}
*/
module.exports = function () {
if (process.env.NODEJS_OS_MONITOR_ENABLED === 'false') {
// in case SPM JAVA OS monitor is used,
// node based agents don't need to collect OS Metrics
return new Agent({
start: function (agent) { this.agent = agent },
stop: function () {}
})
}
if (os.platform() === 'linux') {
try {
var LinuxAgent = require('./linuxAgent.js')
var lAgent = new LinuxAgent()
return lAgent
} catch (err) {
SpmAgent.Logger.error('Cannot initialize linux agent:' + err)
}
}
var osAgent = new Agent(
{
diskFree: function (agent) {
if (os.platform() !== 'darwin') {
return
}
diskfree(function dfMetrics (err, data) {
if (err) {
return logger.error('Error in df() for disk-usage metrics:' + err)
}
if (data && data.length > 0) {
data.forEach(function (disk) {
if (/\/dev\/.+/i.test(disk.filesystem)) {
var dev = disk.filesystem.split('/')[2]
var usedName = 'collectd5-disk-space-used\tdf-' + dev + '/df_complex-used'
var usedValue = disk.used * 1024
var freeName = 'collectd5-disk-space-free\tdf-' + dev + '/df_complex-free'
var freeValue = disk.available * 1024
agent.addMetrics({
ts: Date.now(),
name: usedName,
value: usedValue,
sct: 'OS'
})
agent.addMetrics({
ts: Date.now(),
name: freeName,
value: freeValue,
sct: 'OS'
})
}
})
}
})
},
start: function (agent) {
this.agent = agent
var cpuLastValues = {}
var statsInterval = Math.max(config.collectionInterval || 20000, 20000) || 20000
if (statsInterval < 20000) {
statsInterval = 20000
}
os.cpus().forEach(function (cpu, i) {
cpuLastValues[i] = {idle: 0, user: 0, sys: 0, irq: 0, nice: 0}
})
var cpuProperties = ['user', 'nice', 'irq', 'sys', 'idle']
if (cluster.isMaster || process.env.NODE_APP_INSTANCE === 0 || process.env.SPM_MASTER_MODE === '1' || process.env.STARTUP === 'true') {
var timerId = setInterval(function () {
var time = new Date().getTime()
var metrics = {}
this.diskFree(agent)
metrics['collectd-sys-load'] = os.loadavg()
metrics['collectd-mem-free'] = os.freemem()
metrics['collectd-mem-used'] = os.totalmem() - os.freemem()
os.cpus().forEach(function (cpu, i) {
var cpuTotal = 0
cpuProperties.forEach(function (property) {
cpuLastValues[i][property] = cpu.times[property] - cpuLastValues[i][property]
cpuTotal = cpuTotal + cpuLastValues[i][property]
})
metrics['collectd-cpu-usr\tcpu-' + i + '/cpu-user'] = (cpuLastValues[i].user / cpuTotal) * 100
metrics['collectd-cpu-nic\tcpu-' + i + '/cpu-nice'] = (cpuLastValues[i].nice / cpuTotal) * 100
metrics['collectd-cpu-sys\tcpu-' + i + '/cpu-system'] = (cpuLastValues[i].sys / cpuTotal) * 100
metrics['collectd-cpu-idl\tcpu-' + i + '/cpu-idle'] = (cpuLastValues[i].idle / cpuTotal) * 100
metrics['collectd-cpu-int\tcpu-' + i + '/cpu-interrupt'] = (cpuLastValues[i].irq / cpuTotal) * 100
// We can't get this values from node.js standard API
metrics['collectd-cpu-ste\tcpu-' + i + '/cpu-steal'] = 0.0001
metrics['collectd-cpu-sir\tcpu-' + i + '/cpu-softirq'] = 0.0001
metrics['collectd-cpu-wait\tcpu-' + i + '/cpu-wait'] = 0.0001
})
// setting "sct" parameter for spm-sender to use specific collectd format when transmitting to receiver.
for (var x in metrics) {
agent.addMetrics({ts: time, name: x, value: metrics[x], sct: 'OS'})
}
}.bind(this), statsInterval)
if (timerId.unref) {
timerId.unref()
}
}
}
}
)
return osAgent
}