mirror of
https://github.com/ptarmiganlabs/butler-sos.git
synced 2025-12-25 01:02:50 -05:00
Add initial InfluxDB v3 support - schema and first function
Co-authored-by: mountaindude <1029262+mountaindude@users.noreply.github.com>
This commit is contained in:
committed by
Göran Sander
parent
c156c746a9
commit
3a0592967c
102
src/globals.js
102
src/globals.js
@@ -701,6 +701,19 @@ Configuration File:
|
|||||||
this.logger.info(
|
this.logger.info(
|
||||||
`CONFIG: Influxdb retention policy duration: ${this.config.get('Butler-SOS.influxdbConfig.v2Config.retentionDuration')}`
|
`CONFIG: Influxdb retention policy duration: ${this.config.get('Butler-SOS.influxdbConfig.v2Config.retentionDuration')}`
|
||||||
);
|
);
|
||||||
|
} else if (this.config.get('Butler-SOS.influxdbConfig.version') === 3) {
|
||||||
|
this.logger.info(
|
||||||
|
`CONFIG: Influxdb organisation: ${this.config.get('Butler-SOS.influxdbConfig.v3Config.org')}`
|
||||||
|
);
|
||||||
|
this.logger.info(
|
||||||
|
`CONFIG: Influxdb database: ${this.config.get('Butler-SOS.influxdbConfig.v3Config.database')}`
|
||||||
|
);
|
||||||
|
this.logger.info(
|
||||||
|
`CONFIG: Influxdb bucket name: ${this.config.get('Butler-SOS.influxdbConfig.v3Config.bucket')}`
|
||||||
|
);
|
||||||
|
this.logger.info(
|
||||||
|
`CONFIG: Influxdb retention policy duration: ${this.config.get('Butler-SOS.influxdbConfig.v3Config.retentionDuration')}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`CONFIG: Influxdb version ${this.config.get('Butler-SOS.influxdbConfig.version')} is not supported!`
|
`CONFIG: Influxdb version ${this.config.get('Butler-SOS.influxdbConfig.version')} is not supported!`
|
||||||
@@ -863,13 +876,28 @@ Configuration File:
|
|||||||
const token = this.config.get('Butler-SOS.influxdbConfig.v2Config.token');
|
const token = this.config.get('Butler-SOS.influxdbConfig.v2Config.token');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.influx = new InfluxDB2({ url, token });
|
this.influx = new InfluxDB({ url, token });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`INFLUXDB2 INIT: Error creating InfluxDB 2 client: ${this.getErrorMessage(err)}`
|
`INFLUXDB2 INIT: Error creating InfluxDB 2 client: ${this.getErrorMessage(err)}`
|
||||||
);
|
);
|
||||||
this.logger.error(`INFLUXDB2 INIT: Exiting.`);
|
this.logger.error(`INFLUXDB2 INIT: Exiting.`);
|
||||||
}
|
}
|
||||||
|
} else if (this.config.get('Butler-SOS.influxdbConfig.version') === 3) {
|
||||||
|
// Set up Influxdb v3 client (uses same client library as v2)
|
||||||
|
const url = `http://${this.config.get('Butler-SOS.influxdbConfig.host')}:${this.config.get(
|
||||||
|
'Butler-SOS.influxdbConfig.port'
|
||||||
|
)}`;
|
||||||
|
const token = this.config.get('Butler-SOS.influxdbConfig.v3Config.token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.influx = new InfluxDB({ url, token });
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.error(
|
||||||
|
`INFLUXDB3 INIT: Error creating InfluxDB 3 client: ${this.getErrorMessage(err)}`
|
||||||
|
);
|
||||||
|
this.logger.error(`INFLUXDB3 INIT: Exiting.`);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`CONFIG: Influxdb version ${this.config.get('Butler-SOS.influxdbConfig.version')} is not supported!`
|
`CONFIG: Influxdb version ${this.config.get('Butler-SOS.influxdbConfig.version')} is not supported!`
|
||||||
@@ -1114,6 +1142,78 @@ Configuration File:
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else if (this.config.get('Butler-SOS.influxdbConfig.version') === 3) {
|
||||||
|
// Get config
|
||||||
|
const org = this.config.get('Butler-SOS.influxdbConfig.v3Config.org');
|
||||||
|
const database = this.config.get('Butler-SOS.influxdbConfig.v3Config.database');
|
||||||
|
const bucketName = this.config.get('Butler-SOS.influxdbConfig.v3Config.bucket');
|
||||||
|
const description = this.config.get('Butler-SOS.influxdbConfig.v3Config.description');
|
||||||
|
const token = this.config.get('Butler-SOS.influxdbConfig.v3Config.token');
|
||||||
|
const retentionDuration = this.config.get(
|
||||||
|
'Butler-SOS.influxdbConfig.v3Config.retentionDuration'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.influx &&
|
||||||
|
this.config.get('Butler-SOS.influxdbConfig.enable') === true &&
|
||||||
|
org?.length > 0 &&
|
||||||
|
database?.length > 0 &&
|
||||||
|
bucketName?.length > 0 &&
|
||||||
|
token?.length > 0 &&
|
||||||
|
retentionDuration?.length > 0
|
||||||
|
) {
|
||||||
|
enableInfluxdb = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableInfluxdb) {
|
||||||
|
// For InfluxDB v3, we use the database directly
|
||||||
|
this.logger.info(
|
||||||
|
`INFLUXDB3: Using organization "${org}" with database "${database}"`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create array of per-server writeAPI objects for v3
|
||||||
|
// Each object has two properties: host and writeAPI, where host can be used as key later on
|
||||||
|
this.serverList.forEach((server) => {
|
||||||
|
// Get per-server tags
|
||||||
|
const tags = getServerTags(this.logger, server);
|
||||||
|
|
||||||
|
// advanced write options for InfluxDB v3
|
||||||
|
const writeOptions = {
|
||||||
|
/* default tags to add to every point */
|
||||||
|
defaultTags: tags,
|
||||||
|
|
||||||
|
/* maximum time in millis to keep points in an unflushed batch, 0 means don't periodically flush */
|
||||||
|
flushInterval: 5000,
|
||||||
|
|
||||||
|
/* the count of internally-scheduled retries upon write failure, the delays between write attempts follow an exponential backoff strategy if there is no Retry-After HTTP header */
|
||||||
|
maxRetries: 2, // do not retry writes
|
||||||
|
|
||||||
|
// ... there are more write options that can be customized, see
|
||||||
|
// https://influxdata.github.io/influxdb-client-js/influxdb-client.writeoptions.html and
|
||||||
|
// https://influxdata.github.io/influxdb-client-js/influxdb-client.writeretryoptions.html
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
// For InfluxDB v3, we use database instead of bucket
|
||||||
|
const serverWriteApi = this.influx.getWriteApi(
|
||||||
|
org,
|
||||||
|
database,
|
||||||
|
'ns',
|
||||||
|
writeOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save to global variable, using serverName as key
|
||||||
|
this.influxWriteApi.push({
|
||||||
|
serverName: server.serverName,
|
||||||
|
writeAPI: serverWriteApi,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.error(
|
||||||
|
`INFLUXDB3: Error getting write API: ${this.getErrorMessage(err)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -316,6 +316,19 @@ export const destinationsSchema = {
|
|||||||
},
|
},
|
||||||
port: { type: 'number' },
|
port: { type: 'number' },
|
||||||
version: { type: 'number' },
|
version: { type: 'number' },
|
||||||
|
v3Config: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
org: { type: 'string' },
|
||||||
|
bucket: { type: 'string' },
|
||||||
|
database: { type: 'string' },
|
||||||
|
description: { type: 'string' },
|
||||||
|
token: { type: 'string' },
|
||||||
|
retentionDuration: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: ['org', 'bucket', 'database', 'description', 'token', 'retentionDuration'],
|
||||||
|
additionalProperties: false,
|
||||||
|
},
|
||||||
v2Config: {
|
v2Config: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
@@ -546,6 +546,113 @@ export async function postHealthMetricsToInfluxdb(serverName, host, body, server
|
|||||||
`HEALTH METRICS: Error saving health data to InfluxDB v2! ${globals.getErrorMessage(err)}`
|
`HEALTH METRICS: Error saving health data to InfluxDB v2! ${globals.getErrorMessage(err)}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} else if (globals.config.get('Butler-SOS.influxdbConfig.version') === 3) {
|
||||||
|
// Only write to InfluxDB if the global influxWriteApi object has been initialized
|
||||||
|
if (!globals.influxWriteApi) {
|
||||||
|
globals.logger.warn(
|
||||||
|
'HEALTH METRICS: Influxdb write API object not initialized. Data will not be sent to InfluxDB'
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find writeApi for the server specified by serverName
|
||||||
|
const writeApi = globals.influxWriteApi.find(
|
||||||
|
(element) => element.serverName === serverName
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ensure that the writeApi object was found
|
||||||
|
if (!writeApi) {
|
||||||
|
globals.logger.warn(
|
||||||
|
`HEALTH METRICS: Influxdb write API object not found for host ${host}. Data will not be sent to InfluxDB`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new point with the data to be written to InfluxDB v3
|
||||||
|
const points = [
|
||||||
|
new Point('sense_server')
|
||||||
|
.stringField('version', body.version)
|
||||||
|
.stringField('started', body.started)
|
||||||
|
.stringField('uptime', formattedTime),
|
||||||
|
|
||||||
|
new Point('mem')
|
||||||
|
.floatField('comitted', body.mem.committed)
|
||||||
|
.floatField('allocated', body.mem.allocated)
|
||||||
|
.floatField('free', body.mem.free),
|
||||||
|
|
||||||
|
new Point('apps')
|
||||||
|
.intField('active_docs_count', body.apps.active_docs.length)
|
||||||
|
.intField('loaded_docs_count', body.apps.loaded_docs.length)
|
||||||
|
.intField('in_memory_docs_count', body.apps.in_memory_docs.length)
|
||||||
|
.stringField(
|
||||||
|
'active_docs',
|
||||||
|
globals.config.get('Butler-SOS.influxdbConfig.includeFields.activeDocs')
|
||||||
|
? body.apps.active_docs
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
.stringField(
|
||||||
|
'active_docs_names',
|
||||||
|
globals.config.get('Butler-SOS.appNames.enableAppNameExtract') &&
|
||||||
|
globals.config.get('Butler-SOS.influxdbConfig.includeFields.activeDocs')
|
||||||
|
? activeSessionDocNames
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
.stringField(
|
||||||
|
'loaded_docs',
|
||||||
|
globals.config.get('Butler-SOS.influxdbConfig.includeFields.loadedDocs')
|
||||||
|
? body.apps.loaded_docs
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
.stringField(
|
||||||
|
'loaded_docs_names',
|
||||||
|
globals.config.get('Butler-SOS.appNames.enableAppNameExtract') &&
|
||||||
|
globals.config.get('Butler-SOS.influxdbConfig.includeFields.loadedDocs')
|
||||||
|
? loadedSessionDocNames
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
.stringField(
|
||||||
|
'in_memory_docs',
|
||||||
|
globals.config.get('Butler-SOS.influxdbConfig.includeFields.inMemoryDocs')
|
||||||
|
? body.apps.in_memory_docs
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
.stringField(
|
||||||
|
'in_memory_docs_names',
|
||||||
|
globals.config.get('Butler-SOS.appNames.enableAppNameExtract') &&
|
||||||
|
globals.config.get('Butler-SOS.influxdbConfig.includeFields.inMemoryDocs')
|
||||||
|
? inMemorySessionDocNames
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
.intField('calls', body.apps.calls)
|
||||||
|
.intField('selections', body.apps.selections),
|
||||||
|
|
||||||
|
new Point('cpu').intField('total', body.cpu.total),
|
||||||
|
|
||||||
|
new Point('session')
|
||||||
|
.intField('active', body.session.active)
|
||||||
|
.intField('total', body.session.total),
|
||||||
|
|
||||||
|
new Point('users')
|
||||||
|
.intField('active', body.users.active)
|
||||||
|
.intField('total', body.users.total),
|
||||||
|
|
||||||
|
new Point('cache')
|
||||||
|
.intField('hits', body.cache.hits)
|
||||||
|
.intField('lookups', body.cache.lookups)
|
||||||
|
.intField('added', body.cache.added)
|
||||||
|
.intField('replaced', body.cache.replaced)
|
||||||
|
.intField('bytes_added', body.cache.bytes_added),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Write to InfluxDB
|
||||||
|
try {
|
||||||
|
const res = await writeApi.writeAPI.writePoints(points);
|
||||||
|
globals.logger.debug(`HEALTH METRICS: Wrote data to InfluxDB v3`);
|
||||||
|
} catch (err) {
|
||||||
|
globals.logger.error(
|
||||||
|
`HEALTH METRICS: Error saving health data to InfluxDB v3! ${globals.getErrorMessage(err)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user