logzio-nodejs-metrics-sdk
Advanced tools
Comparing version 0.3.0 to 0.4.0
{ | ||
"name": "logzio-nodejs-metrics-sdk", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "Logz.io node.js metrics Exporter allows user to send collected metrics to the Logz.io using OpenTelemetry SDK ", | ||
@@ -21,3 +21,3 @@ "main": "src/index.js", | ||
"engines": { | ||
"node": ">=8.0.0" | ||
"node": ">=12.0.0" | ||
}, | ||
@@ -41,5 +41,4 @@ "files": [ | ||
"codecov": "3.8.2", | ||
"cpx": "1.5.0", | ||
"express-http-context": "^1.2.4", | ||
"mocha": "^7.2.0", | ||
"mocha": "^8.4.0", | ||
"nyc": "15.1.0", | ||
@@ -61,2 +60,3 @@ "request-promise": "^4.2.6", | ||
"@opentelemetry/sdk-metrics-base": "^0.27.0", | ||
"axios": "1.1.3", | ||
"google-protobuf": "^3.21.0", | ||
@@ -66,7 +66,6 @@ "nock": "^13.2.9", | ||
"request": "^2.88.2", | ||
"requestretry": "^7.1.0", | ||
"snappyjs": "^0.6.1", | ||
"winston": "^3.8.1" | ||
"winston": "^3.9.0" | ||
}, | ||
"gitHead": "7750282034ee58bdd257446c2970f01307d7522a" | ||
} |
@@ -17,3 +17,4 @@ ## Logz.io nodejs metrics sdk | ||
``` | ||
npm install logzio-nodejs-metrics-sdk@0.3.0 | ||
npm install logzio-nodejs-metrics-sdk@0.4.0 | ||
npm install @opentelemetry/sdk-metrics-base@0.27.0 | ||
``` | ||
@@ -54,3 +55,3 @@ | ||
// Record some value | ||
requestCounter.bind(labels).add(1); | ||
requestCounter.add(1, labels); | ||
// In logzio Metrics you will see the following metric: | ||
@@ -90,3 +91,3 @@ // Counter_total{environment: 'prod'} 1.0 | ||
exporter: metricExporter, | ||
interval: 15000, // Push interval in seconds | ||
interval: 15000, // Push interval in miliseconds | ||
}).getMeter('example-exporter'); | ||
@@ -107,5 +108,4 @@ ``` | ||
// Record some values | ||
upDownCounter.bind(labels); | ||
upDownCounter.add(5); | ||
upDownCounter.add(-1); | ||
upDownCounter.add(5, labels); | ||
upDownCounter.add(-1, labels); | ||
// In logzio you will see the following metric: | ||
@@ -125,5 +125,4 @@ // UpDownCounter{environment: 'prod'} 4.0 | ||
// Record some values | ||
histogram.bind(labels); | ||
histogram.record(30); | ||
histogram.record(20); | ||
histogram.record(30, labels); | ||
histogram.record(20), labels; | ||
// In logzio you will see the following metrics: | ||
@@ -136,3 +135,11 @@ // test_histogram_sum{environment: 'prod'} 50.0 | ||
## Update log | ||
**0.4.0** | ||
Breaking changes: | ||
- Drop support for Nodejs `8.*` `10.*` | ||
Changelog: | ||
- Fix bug which makes it crash if no metrics created/written before the first interval (@chapost1) | ||
- Using `axios` instead of `requestretry` (@chapost1) | ||
**0.3.0** | ||
@@ -139,0 +146,0 @@ |
185
src/util.js
@@ -23,3 +23,3 @@ "use strict"; | ||
const logger = require('./logging').logger | ||
const request = require('requestretry'); | ||
const axios = require('axios'); | ||
let lost = 0; | ||
@@ -39,81 +39,132 @@ | ||
function exporterRetryStrategy(err, response, body, options){ | ||
try { | ||
const retryCodes = [408, 500, 502, 503, 504, 522, 524]; | ||
const shouldRetry = retryCodes.includes(response.statusCode); | ||
if (shouldRetry){ | ||
options.headers['logzio-shipper'] = `nodejs-metrics/1.0.0/${response.attempts}/${lost}`; | ||
logger.log({level: "warn", message: `Faild to export, attempt number: ${response.attempts}, retrying again in ${options.retryDelay/1000}s`,}); | ||
} | ||
return { | ||
mustRetry: shouldRetry, | ||
options: options, | ||
} | ||
} | ||
catch (e) { | ||
logger.log({ | ||
level: "error", | ||
message: err.message | ||
function shouldRetry(status, attempts, maxAttempts) { | ||
const retryCodes = [408, 500, 502, 503, 504, 522, 524]; | ||
return retryCodes.includes(status) && attempts < maxAttempts; | ||
} | ||
function axiosRetry({ | ||
url, | ||
payload, | ||
baseHeaders, | ||
httpAgent, | ||
response, | ||
maxAttempts, | ||
retryMS, | ||
callback | ||
} = {}) { | ||
process.nextTick(execute); | ||
function execute() { | ||
const headers = getRequestHeaders(baseHeaders, response.attempts); | ||
const requestOptions = { | ||
headers, | ||
httpAgent, | ||
validateStatus: function (status) { | ||
if (status < 200 || status > 204) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
}; | ||
response.options = { | ||
headers, | ||
}; | ||
response.attempts += 1; | ||
axios.post(url, payload, requestOptions) | ||
.then(res => { | ||
if (shouldRetry(res.status, response.attempts, maxAttempts)) { | ||
setTimeout(() => execute.call(this), retryMS); | ||
} else { | ||
response.status = res.status; | ||
callback(null); | ||
} | ||
}) | ||
.catch(error => { | ||
if (error.response && error.response.status) { | ||
if (shouldRetry(error.response.status, response.attempts, maxAttempts)) { | ||
setTimeout(() => execute.call(this), retryMS); | ||
} else { | ||
response.status = error.response.status; | ||
callback(error); | ||
} | ||
} else { | ||
callback(error); | ||
} | ||
}); | ||
} | ||
} | ||
function send(collector, objects) { | ||
function makeWriteRequest(collector, objects) { | ||
const serviceRequest = collector.convert(objects); | ||
const write_request = transform.toTimeSeries(serviceRequest); | ||
const bytes = write_request.serializeBinary(); | ||
const writeRequest = transform.toTimeSeries(serviceRequest); | ||
return writeRequest; | ||
} | ||
function makePayload(writeRequest) { | ||
const bytes = writeRequest.serializeBinary(); | ||
const payload = SnappyJS.compress(bytes); | ||
let response; | ||
if (write_request.wrappers_["1"].length > 0) { | ||
//Send with htttp | ||
const rawHeaders = { | ||
"Content-Encoding": "snappy", | ||
"Content-Type": "application/x-protobuf", | ||
"X-Prometheus-Remote-Write-Version": "0.1.0", | ||
"logzio-shipper": `nodejs-metrics/1.0.0/0/${lost}`, | ||
}; | ||
const headers = {...rawHeaders,...collector.headers} | ||
const options = { | ||
uri: collector.url, | ||
method: 'POST', | ||
agent: collector.agent, | ||
body: payload, | ||
headers: headers, | ||
return payload; | ||
} | ||
function getRequestHeaders(baseHeaders, attempts) { | ||
const rawHeaders = { | ||
"Content-Encoding": "snappy", | ||
"Content-Type": "application/x-protobuf", | ||
"X-Prometheus-Remote-Write-Version": "0.1.0", | ||
"logzio-shipper": `nodejs-metrics/1.0.0/${attempts}/${lost}`, | ||
}; | ||
const headers = {...rawHeaders, ...baseHeaders} | ||
return headers; | ||
} | ||
function send(collector, objects) { | ||
const response = { | ||
options: {}, | ||
attempts: 0, | ||
status: -1, | ||
}; | ||
const writeRequest = makeWriteRequest(collector, objects); | ||
if (!(writeRequest && writeRequest.wrappers_)) { | ||
// no data | ||
logger.log({level: 'info', message: 'No timeseries to send'}); | ||
return; | ||
} | ||
const timeSeriesCount = writeRequest.wrappers_["1"].length; | ||
if (0 < timeSeriesCount) { | ||
logger.log({level: 'info', message: `Sending bulk of ${timeSeriesCount} timeseries`}); | ||
axiosRetry({ | ||
url: collector.url, | ||
payload: makePayload(writeRequest), | ||
httpAgent: collector.agent, | ||
baseHeaders: collector.headers, | ||
maxAttempts: 3, | ||
retryDelay: 2000, | ||
retryStrategy: exporterRetryStrategy | ||
} | ||
logger.log({level: 'info', message: `Sending bulk of ${write_request.wrappers_["1"].length} timeseries`}); | ||
response = request(options, function (err, response, body) { | ||
// this callback will only be called when the request succeeded or after maxAttempts or on error | ||
try { | ||
if (response.statusCode < 200 || response.statusCode > 204 ) { | ||
logger.log({ | ||
level: "warn", | ||
message: `Export failed after ${response.attempts} attempts. Status code: ${response.statusCode}` | ||
}) | ||
lost += write_request.wrappers_["1"].length; | ||
return response; | ||
} else { | ||
logger.log({ | ||
level: "info", | ||
message: `Export Succeeded after ${response.attempts} attempts. Status code: ${response.statusCode}` | ||
}) | ||
lost = 0; | ||
return response; | ||
} | ||
} | ||
catch (e) { | ||
logger.log({ | ||
retryMS: 2000, | ||
response, | ||
callback: postRequest | ||
}); | ||
function postRequest(err) { | ||
if (err) { | ||
lost += timeSeriesCount; | ||
return logger.log({ | ||
level: "error", | ||
message: `Failed to export error : ${err.message}` | ||
}) | ||
}); | ||
} | ||
}); | ||
return response; | ||
lost = 0; | ||
logger.log({ | ||
level: "info", | ||
message: `Export Succeeded after ${response.attempts} attempts. Status code: ${response.status}` | ||
}); | ||
} | ||
} else { | ||
logger.log({level: "info", message: "No timeseries to send"}) | ||
return | ||
} | ||
return response; | ||
} | ||
exports.send = send; | ||
exports.send = send; |
60929
15
1203
153
+ Addedaxios@1.1.3
+ Addedaxios@1.1.3(transitive)
+ Addedfollow-redirects@1.15.6(transitive)
+ Addedform-data@4.0.0(transitive)
+ Addedproxy-from-env@1.1.0(transitive)
- Removedrequestretry@^7.1.0
- Removedlodash@4.17.21(transitive)
- Removedrequestretry@7.1.0(transitive)
Updatedwinston@^3.9.0