mirror of
https://github.com/ptarmiganlabs/butler-sos.git
synced 2025-12-19 17:58:18 -05:00
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,6 +13,7 @@ ssl/*
|
||||
*.tmp
|
||||
|
||||
# Logs
|
||||
log/
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
12
changelog.md
12
changelog.md
@@ -2,6 +2,18 @@
|
||||
|
||||
Releases are [available on Github](https://github.com/ptarmiganlabs/butler-sos/releases).
|
||||
|
||||
## 5.6.0
|
||||
|
||||
### New features
|
||||
|
||||
1. . ([#150](https://github.com/ptarmiganlabs/butler/issues/150))
|
||||
|
||||
### Fixes and patches
|
||||
|
||||
1. Dependencies updated to stay sharp and secure.
|
||||
|
||||
### Changed behavior and/or breaking changes
|
||||
|
||||
## 5.5.3
|
||||
|
||||
- Dependencies updated to stay sharp and secure.
|
||||
|
||||
48
docs/log4net_user-audit-event/LocalLogConfig.xml
Normal file
48
docs/log4net_user-audit-event/LocalLogConfig.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="EventSession" type="log4net.Appender.UdpAppender">
|
||||
<filter type="log4net.Filter.StringMatchFilter">
|
||||
<param name="stringToMatch" value="Start session for user" />
|
||||
</filter>
|
||||
<filter type="log4net.Filter.StringMatchFilter">
|
||||
<param name="stringToMatch" value="Stop session for user" />
|
||||
</filter>
|
||||
<filter type="log4net.Filter.DenyAllFilter" />
|
||||
<param name="remoteAddress" value="<FQDN or IP of server where Butler is running>" />
|
||||
<param name="remotePort" value="9997" />
|
||||
<param name="encoding" value="utf-8" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<converter>
|
||||
<param name="name" value="hostname" />
|
||||
<param name="type" value="Qlik.Sense.Logging.log4net.Layout.Pattern.HostNamePatternConverter" />
|
||||
</converter>
|
||||
<param name="conversionpattern" value="/proxy-session/;%hostname;%property{Command};%property{UserDirectory};%property{UserId};%property{Origin};%property{Context};%message" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="EventConnection" type="log4net.Appender.UdpAppender">
|
||||
<filter type="log4net.Filter.StringMatchFilter">
|
||||
<param name="stringToMatch" value="connection Opened for session" />
|
||||
</filter>
|
||||
<filter type="log4net.Filter.StringMatchFilter">
|
||||
<param name="stringToMatch" value="connection Closed for session" />
|
||||
</filter>
|
||||
<filter type="log4net.Filter.DenyAllFilter" />
|
||||
<param name="remoteAddress" value="<FQDN or IP of server where Butler is running>" />
|
||||
<param name="remotePort" value="9997" />
|
||||
<param name="encoding" value="utf-8" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<converter>
|
||||
<param name="name" value="hostname" />
|
||||
<param name="type" value="Qlik.Sense.Logging.log4net.Layout.Pattern.HostNamePatternConverter" />
|
||||
</converter>
|
||||
<param name="conversionpattern" value="/proxy-connection/;%hostname;%property{Command};%property{UserDirectory};%property{UserId};%property{Origin};%property{Context};%message" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<logger name="AuditActivity.Proxy">
|
||||
<appender-ref ref="EventSession" />
|
||||
<appender-ref ref="EventConnection" />
|
||||
</logger>
|
||||
</configuration>
|
||||
@@ -9,6 +9,8 @@ const sessionMetrics = require('./lib/sessionmetrics');
|
||||
const appNamesExtract = require('./lib/appnamesextract');
|
||||
const heartbeat = require('./lib/heartbeat');
|
||||
const serviceUptime = require('./lib/service_uptime');
|
||||
const udp = require('./lib/udp_handlers');
|
||||
const telemetry = require('./lib/telemetry');
|
||||
|
||||
globals.initInfluxDB();
|
||||
|
||||
@@ -18,7 +20,7 @@ if (globals.config.get('Butler-SOS.uptimeMonitor.enabled') == true) {
|
||||
|
||||
mainScript();
|
||||
|
||||
function mainScript() {
|
||||
async function mainScript() {
|
||||
// Load certificates to use when connecting to healthcheck API
|
||||
var path = require('path'),
|
||||
certFile = path.resolve(__dirname, globals.config.get('Butler-SOS.cert.clientCert')),
|
||||
@@ -54,22 +56,65 @@ function mainScript() {
|
||||
heartbeat.setupHeartbeatTimer(globals.config, globals.logger);
|
||||
}
|
||||
|
||||
// Set specific log level (if/when needed to override the config file setting)
|
||||
// Possible values are { error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5 }
|
||||
// Default is to use log level defined in config file
|
||||
globals.logger.info('--------------------------------------');
|
||||
globals.logger.info('Starting Butler SOS');
|
||||
globals.logger.info(`Log level: ${globals.getLoggingLevel()}`);
|
||||
globals.logger.info(`App version: ${globals.appVersion}`);
|
||||
globals.logger.info('--------------------------------------');
|
||||
try {
|
||||
// Get host info
|
||||
globals.hostInfo = await globals.initHostInfo();
|
||||
globals.logger.debug('CONFIG: Initiated host info data structures');
|
||||
|
||||
// Log info about what Qlik Sense certificates are being used
|
||||
globals.logger.debug(`Client cert: ${certFile}`);
|
||||
globals.logger.debug(`Client cert key: ${keyFile}`);
|
||||
globals.logger.debug(`CA cert: ${caFile}`);
|
||||
// Set specific log level (if/when needed to override the config file setting)
|
||||
// Possible values are { error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5 }
|
||||
// Default is to use log level defined in config file
|
||||
globals.logger.info('--------------------------------------');
|
||||
globals.logger.info('Starting Butler SOS');
|
||||
globals.logger.info(`Log level: ${globals.getLoggingLevel()}`);
|
||||
globals.logger.info(`App version: ${globals.appVersion}`);
|
||||
globals.logger.info('');
|
||||
globals.logger.info(`Node version : ${globals.hostInfo.node.nodeVersion}`);
|
||||
globals.logger.info(`Architecture : ${globals.hostInfo.si.os.arch}`);
|
||||
globals.logger.info(`Platform : ${globals.hostInfo.si.os.platform}`);
|
||||
globals.logger.info(`Release : ${globals.hostInfo.si.os.release}`);
|
||||
globals.logger.info(`Distro : ${globals.hostInfo.si.os.distro}`);
|
||||
globals.logger.info(`Codename : ${globals.hostInfo.si.os.codename}`);
|
||||
globals.logger.info(`Virtual : ${globals.hostInfo.si.system.virtual}`);
|
||||
globals.logger.info(`Processors : ${globals.hostInfo.si.cpu.processors}`);
|
||||
globals.logger.info(`Physical cores : ${globals.hostInfo.si.cpu.physicalCores}`);
|
||||
globals.logger.info(`Cores : ${globals.hostInfo.si.cpu.cores}`);
|
||||
globals.logger.info(`Docker arch. : ${globals.hostInfo.si.cpu.hypervizor}`);
|
||||
globals.logger.info(`Total memory : ${globals.hostInfo.si.memory.total}`);
|
||||
globals.logger.info('--------------------------------------');
|
||||
|
||||
// Log info about what Qlik Sense certificates are being used
|
||||
globals.logger.info(`Client cert: ${certFile}`);
|
||||
globals.logger.info(`Client cert key: ${keyFile}`);
|
||||
globals.logger.info(`CA cert: ${caFile}`);
|
||||
|
||||
// Set up anon usage reports, if enabled
|
||||
if (
|
||||
globals.config.has('Butler-SOS.anonTelemetry') == false ||
|
||||
(globals.config.has('Butler-SOS.anonTelemetry') == true && globals.config.get('Butler-SOS.anonTelemetry') == true)
|
||||
) {
|
||||
telemetry.setupAnonUsageReportTimer();
|
||||
globals.logger.verbose('MAIN: Anonymous telemetry reporting has been set up.');
|
||||
}
|
||||
} catch (err) {
|
||||
globals.logger.error(`CONFIG: Error initiating host info: ${err}`);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Set up UDP handler
|
||||
if (globals.config.has('Butler-SOS.udpServerConfig.enable') && globals.config.get('Butler-SOS.udpServerConfig.enable')) {
|
||||
udp.udpInitUserActivityServer();
|
||||
|
||||
globals.logger.debug(`MAIN: Server for UDP server: ${globals.udpServer.host}`);
|
||||
|
||||
// Start UDP server for user activity events
|
||||
globals.udpServer.userActivitySocket.bind(
|
||||
globals.udpServer.portUserActivity,
|
||||
globals.udpServer.host,
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Start Docker healthcheck REST server on port set in config file
|
||||
if (globals.config.get('Butler-SOS.dockerHealthCheck.enabled') == true) {
|
||||
globals.logger.verbose('MAIN: Starting Docker healthcheck server...');
|
||||
@@ -77,7 +122,7 @@ function mainScript() {
|
||||
restServer.listen(globals.config.get('Butler-SOS.dockerHealthCheck.port'), function () {
|
||||
globals.logger.info('MAIN: Docker healthcheck server now listening');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Set up extraction of data from log db
|
||||
if (globals.config.get('Butler-SOS.logdb.enableLogDb') == true) {
|
||||
|
||||
@@ -4,6 +4,11 @@ var config = require('config');
|
||||
const winston = require('winston');
|
||||
require('winston-daily-rotate-file');
|
||||
const path = require('path');
|
||||
var dgram = require('dgram');
|
||||
const si = require('systeminformation');
|
||||
const os = require('os');
|
||||
let crypto = require('crypto');
|
||||
|
||||
// const verifyConfig = require('./lib/verifyConfig');
|
||||
|
||||
const Influx = require('influx');
|
||||
@@ -58,6 +63,28 @@ const getLoggingLevel = () => {
|
||||
}).level;
|
||||
};
|
||||
|
||||
// ------------------------------------
|
||||
// UDP server connection parameters
|
||||
var udpServer = {};
|
||||
try {
|
||||
udpServer.host = config.has('Butler-SOS.udpServerConfig.serverHost')
|
||||
? config.get('Butler-SOS.udpServerConfig.serverHost')
|
||||
: '';
|
||||
|
||||
// Prepare to listen on port X for incoming UDP connections regarding user activity events
|
||||
udpServer.userActivitySocket = dgram.createSocket({
|
||||
type: 'udp4',
|
||||
reuseAddr: true,
|
||||
});
|
||||
|
||||
udpServer.portUserActivity = config.has('Butler-SOS.udpServerConfig.portUserActivityEvents')
|
||||
? config.get('Butler-SOS.udpServerConfig.portUserActivityEvents')
|
||||
: '';
|
||||
} catch (err) {
|
||||
logger.error(`CONFIG: Setting up UDP user activity listener: ${err}`);
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
// Get info on what servers to monitor
|
||||
const serverList = config.get('Butler-SOS.serversToMonitor.servers');
|
||||
|
||||
@@ -72,6 +99,7 @@ const pgPool = new Pool({
|
||||
|
||||
// the pool will emit an error on behalf of any idle clients
|
||||
// it contains if a backend error or network partition happens
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
pgPool.on('error', (err, client) => {
|
||||
logger.error(`CONFIG: Unexpected error on idle client: ${err}`);
|
||||
// process.exit(-1);
|
||||
@@ -207,9 +235,7 @@ const influx = new Influx.InfluxDB({
|
||||
heap_total: Influx.FieldType.FLOAT,
|
||||
process_memory: Influx.FieldType.FLOAT,
|
||||
},
|
||||
tags: [
|
||||
'butler_sos_instance'
|
||||
]
|
||||
tags: ['butler_sos_instance'],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -261,7 +287,7 @@ function initInfluxDB() {
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error(`CONFIG: Error getting list of InfuxDB databases! ${err.stack}`);
|
||||
logger.error(`CONFIG: Error getting list of InfluxDB databases! ${err.stack}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -279,7 +305,67 @@ var mqttClient = mqtt.connect({
|
||||
protocolId: 'MQIsdp',
|
||||
protocolVersion: 3
|
||||
});
|
||||
*/
|
||||
*/
|
||||
|
||||
// Anon telemetry reporting
|
||||
var hostInfo;
|
||||
|
||||
async function initHostInfo() {
|
||||
try {
|
||||
const siCPU = await si.cpu(),
|
||||
siSystem = await si.system(),
|
||||
siMem = await si.mem(),
|
||||
siOS = await si.osInfo(),
|
||||
siDocker = await si.dockerInfo(),
|
||||
siNetwork = await si.networkInterfaces(),
|
||||
siNetworkDefault = await si.networkInterfaceDefault();
|
||||
|
||||
let defaultNetworkInterface = siNetworkDefault;
|
||||
|
||||
let networkInterface = siNetwork.filter(item => {
|
||||
return item.iface === defaultNetworkInterface;
|
||||
});
|
||||
|
||||
let idSrc = networkInterface[0].mac + networkInterface[0].ip4 + config.get('Butler-SOS.logdb.host') + siSystem.uuid;
|
||||
let salt = networkInterface[0].mac;
|
||||
let hash = crypto.createHmac('sha256', salt);
|
||||
hash.update(idSrc);
|
||||
let id = hash.digest('hex');
|
||||
|
||||
|
||||
hostInfo = {
|
||||
id: id,
|
||||
node: {
|
||||
nodeVersion: process.version,
|
||||
versions: process.versions
|
||||
},
|
||||
os: {
|
||||
platform: os.platform(),
|
||||
release: os.release(),
|
||||
version: os.version(),
|
||||
arch: os.arch(),
|
||||
cpuCores: os.cpus().length,
|
||||
type: os.type(),
|
||||
totalmem: os.totalmem(),
|
||||
},
|
||||
si: {
|
||||
cpu: siCPU,
|
||||
system: siSystem,
|
||||
memory: {
|
||||
total: siMem.total,
|
||||
},
|
||||
os: siOS,
|
||||
network: siNetwork,
|
||||
networkDefault: siNetworkDefault,
|
||||
docker: siDocker,
|
||||
},
|
||||
};
|
||||
|
||||
return hostInfo;
|
||||
} catch (err) {
|
||||
logger.error(`CONFIG: Getting host info: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
config,
|
||||
@@ -292,4 +378,7 @@ module.exports = {
|
||||
serverList,
|
||||
initInfluxDB,
|
||||
appNames,
|
||||
udpServer,
|
||||
initHostInfo,
|
||||
hostInfo,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const globals = require('../globals');
|
||||
var _ = require('lodash');
|
||||
const Promise = require('promise');
|
||||
// const Promise = require('promise');
|
||||
|
||||
const sessionAppPrefix = 'SessionApp';
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ function getCertificates(options) {
|
||||
|
||||
function getSessionStatsFromSense(host, virtualProxy, influxTags) {
|
||||
// Current user sessions are retrived using this API:
|
||||
// http://help.qlik.com/en-US/sense-developer/June2019/Subsystems/ProxyServiceAPI/Content/Sense_ProxyServiceAPI/ProxyServiceAPI-Session-Module-API.htm
|
||||
// https://help.qlik.com/en-US/sense-developer/February2021/Subsystems/ProxyServiceAPI/Content/Sense_ProxyServiceAPI/ProxyServiceAPI-Proxy-API.htm
|
||||
|
||||
var options = {};
|
||||
|
||||
|
||||
82
src/lib/telemetry.js
Normal file
82
src/lib/telemetry.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/*eslint strict: ["error", "global"]*/
|
||||
/*eslint no-invalid-this: "error"*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const axios = require('axios');
|
||||
var globals = require('../globals');
|
||||
|
||||
// const telemetryBaseUrl = 'http://localhost:7071/';
|
||||
const telemetryBaseUrl = 'https://ptarmiganlabs-telemetry.azurewebsites.net/';
|
||||
const telemetryUrl = '/api/butlerTelemetry';
|
||||
|
||||
var callRemoteURL = async function () {
|
||||
try {
|
||||
let body = {
|
||||
service: 'butler-sos',
|
||||
serviceVersion: globals.appVersion,
|
||||
system: {
|
||||
id: globals.hostInfo.id,
|
||||
arch: globals.hostInfo.si.os.arch,
|
||||
platform: globals.hostInfo.si.os.platform,
|
||||
release: globals.hostInfo.si.os.release,
|
||||
distro: globals.hostInfo.si.os.distro,
|
||||
codename: globals.hostInfo.si.os.codename,
|
||||
virtual: globals.hostInfo.si.system.virtual,
|
||||
hypervisor: globals.hostInfo.si.os.hypervizor,
|
||||
nodeVersion: globals.hostInfo.node.nodeVersion
|
||||
},
|
||||
enabledFeatures: {
|
||||
feature: {
|
||||
heartbeat: globals.config.has('Butler-SOS.heartbeat.enabled') ? globals.config.get('Butler-SOS.heartbeat.enabled') : false,
|
||||
dockerHealthCheck: globals.config.has('Butler-SOS.dockerHealthCheck.enabled') ? globals.config.get('Butler-SOS.dockerHealthCheck.enabled') : false,
|
||||
uptimeMonitor: globals.config.has('Butler-SOS.uptimeMonitor.enabled') ? globals.config.get('Butler-SOS.uptimeMonitor.enabled') : false,
|
||||
uptimeMonitor_storeInInfluxdb: globals.config.has('Butler-SOS.uptimeMonitor.storeInInfluxdb.butlerSOSMemoryUsage') ? globals.config.get('Butler-SOS.uptimeMonitor.storeInInfluxdb.butlerSOSMemoryUsage') : false,
|
||||
udpServer: globals.config.has('Butler-SOS.udpServerConfig.enable') ? globals.config.get('Butler-SOS.udpServerConfig.enable') : false,
|
||||
logdb: globals.config.has('Butler-SOS.logdb.enableLogDb') ? globals.config.get('Butler-SOS.logdb.enableLogDb') : false,
|
||||
mqtt: globals.config.has('Butler-SOS.mqttConfig.enableMQTT') ? globals.config.get('Butler-SOS.mqttConfig.enableMQTT') : false,
|
||||
influxdb: globals.config.has('Butler-SOS.influxdbConfig.enableInfluxdb') ? globals.config.get('Butler-SOS.influxdbConfig.enableInfluxdb') : false,
|
||||
|
||||
appNames: globals.config.has('Butler-SOS.appNames.enableAppNameExtract') ? globals.config.get('Butler-SOS.appNames.enableAppNameExtract') : false,
|
||||
userSessions: globals.config.has('Butler-SOS.userSessions.enableSessionExtract') ? globals.config.get('Butler-SOS.userSessions.enableSessionExtract') : false,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let axiosConfig = {
|
||||
url: telemetryUrl,
|
||||
method: 'post',
|
||||
baseURL: telemetryBaseUrl,
|
||||
data: body,
|
||||
timeout: 5000,
|
||||
responseType: 'text',
|
||||
};
|
||||
|
||||
await axios.request(axiosConfig);
|
||||
globals.logger.debug('TELEMETRY: Sent anonymous telemetry. Thanks for contributing to making Butler SOS better!');
|
||||
} catch (err) {
|
||||
globals.logger.error('TELEMETRY: Could not send anonymous telemetry.');
|
||||
globals.logger.error(' While not mandatory the telemetry data greatly helps the Butler SOS developers.');
|
||||
globals.logger.error(' It provides insights into which features are used most and what hardware/OSs are most used out there.');
|
||||
globals.logger.error(' This information makes it possible to focus development efforts where they will make most impact and be most valuable.');
|
||||
globals.logger.error('❤️ Thank you for your supporting Butler SOS by allowing telemetry! ❤️');
|
||||
}
|
||||
};
|
||||
|
||||
function setupAnonUsageReportTimer(logger, hostInfo) {
|
||||
try {
|
||||
setInterval(function () {
|
||||
callRemoteURL(logger, hostInfo);
|
||||
// }, 1000*60*60*12); // Report anon usage every 12 hours
|
||||
}, 1000 * 60 * 60 * 6);
|
||||
|
||||
// Do an initial report to the remote URL
|
||||
callRemoteURL(logger, hostInfo);
|
||||
} catch (err) {
|
||||
logger.error(`TELEMETRY: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
setupAnonUsageReportTimer,
|
||||
};
|
||||
65
src/lib/udp_handlers.js
Normal file
65
src/lib/udp_handlers.js
Normal file
@@ -0,0 +1,65 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint strict: ["error", "global"] */
|
||||
|
||||
'use strict';
|
||||
|
||||
// Load global variables and functions
|
||||
var globals = require('../globals');
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Set up UDP server for acting on Sense user activity events
|
||||
// --------------------------------------------------------
|
||||
function udpInitUserActivityServer () {
|
||||
// Handler for UDP server startup event
|
||||
globals.udpServer.userActivitySocket.on('listening', function (message, remote) {
|
||||
var address = globals.udpServer.userActivitySocket.address();
|
||||
|
||||
globals.logger.info(`USER ACTIVITY: UDP server listening on ${address.address}:${address.port}`);
|
||||
});
|
||||
|
||||
// Handler for UDP messages relating to user activity events
|
||||
globals.udpServer.userActivitySocket.on('message', async function (message, remote) {
|
||||
try {
|
||||
// >> Message parts
|
||||
// 0: Message type. Possible values are /proxy-connection/, /proxy-session/
|
||||
// 1: Host
|
||||
// 2: Command
|
||||
// 3: User directory
|
||||
// 4: user ID
|
||||
// 5: Origin
|
||||
// 6: Context
|
||||
// 7: Message. Can contain single quotes and semicolon - handle with care
|
||||
|
||||
// >> Parameter 2 (command):
|
||||
// Start session
|
||||
// Stop session
|
||||
// Open connection
|
||||
// Close connection
|
||||
|
||||
var msgTmp1 = message.toString().split(';'),
|
||||
msg = msgTmp1.slice(0, 7);
|
||||
|
||||
globals.logger.verbose(`USER ACTIVITY: ${msg[1]}: ${msg[2]} for user ${msg[3]}/${msg[4]}`);
|
||||
globals.logger.debug(`USER ACTIVITY details: ${msg}`);
|
||||
|
||||
// // Send MQTT messages
|
||||
// if (msg[2] == 'Start session') {
|
||||
// globals.mqttClient.publish(globals.config.get('Butler-SOS.mqttConfig.sessionStartTopic'), msg[1] + ': ' + msg[3] + '/' + msg[4]);
|
||||
// } else if (msg[2] == 'Stop session') {
|
||||
// globals.mqttClient.publish(globals.config.get('Butler-SOS.mqttConfig.sessionStopTopic'), msg[1] + ': ' + msg[3] + '/' + msg[4]);
|
||||
// } else if (msg[2] == 'Open connection') {
|
||||
// globals.mqttClient.publish(globals.config.get('Butler-SOS.mqttConfig.connectionOpenTopic'), msg[1] + ': ' + msg[3] + '/' + msg[4]);
|
||||
// } else if (msg[2] == 'Close connection') {
|
||||
// globals.mqttClient.publish(globals.config.get('Butler-SOS.mqttConfig.connectionCloseTopic'), msg[1] + ': ' + msg[3] + '/' + msg[4]);
|
||||
// }
|
||||
} catch (err) {
|
||||
globals.logger.error(`USER ACTIVITY: Error processing user activity event: ${err}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
udpInitUserActivityServer
|
||||
};
|
||||
|
||||
3612
src/package-lock.json
generated
3612
src/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "butler-sos",
|
||||
"version": "5.5.3",
|
||||
"version": "5.6.0",
|
||||
"description": "Butler SenseOps Stats (\"Butler SOS\") is a Node.js service publishing operational Qlik Sense metrics to MQTT and Influxdb.",
|
||||
"main": "butler-sos.js",
|
||||
"scripts": {
|
||||
@@ -27,26 +27,26 @@
|
||||
"homepage": "https://github.com/ptarmiganlabs/butler-sos#readme",
|
||||
"dependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"config": "^3.3.3",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"influx": "^5.6.3",
|
||||
"js-yaml": "^3.14.0",
|
||||
"config": "^3.3.4",
|
||||
"influx": "^5.7.0",
|
||||
"js-yaml": "^4.0.0",
|
||||
"later": "^1.2.0",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"moment": "^2.29.1",
|
||||
"moment-precise-range-plugin": "^1.3.0",
|
||||
"mqtt": "^4.2.6",
|
||||
"pg": "^8.5.1",
|
||||
"promise": "^8.1.0",
|
||||
"qrs-interact": "^6.2.0",
|
||||
"qrs-interact": "^6.2.1",
|
||||
"restify": "^8.5.1",
|
||||
"systeminformation": "^5.5.0",
|
||||
"url-join": "^4.0.1",
|
||||
"winston": "^3.3.3",
|
||||
"winston-daily-rotate-file": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.17.0",
|
||||
"jshint": "2.12.0",
|
||||
"eslint": "^7.21.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"jshint": "^2.12.0",
|
||||
"prettier": "^2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user