@ -1,4 +1,3 @@
const { R } = require ( "redbean-node" ) ;
const PrometheusClient = require ( "prom-client" ) ;
const PrometheusClient = require ( "prom-client" ) ;
const { log } = require ( "../src/util" ) ;
const { log } = require ( "../src/util" ) ;
@ -10,102 +9,36 @@ const commonLabels = [
"monitor_port" ,
"monitor_port" ,
] ;
] ;
class Prometheus {
const monitorCertDaysRemaining = new PrometheusClient . Gauge ( {
/ * *
* Metric : monitor _cert _days _remaining
* @ type { PrometheusClient . Gauge < string > | null }
* /
static monitorCertDaysRemaining = null ;
/ * *
* Metric : monitor _cert _is _valid
* @ type { PrometheusClient . Gauge < string > | null }
* /
static monitorCertIsValid = null ;
/ * *
* Metric : monitor _response _time
* @ type { PrometheusClient . Gauge < string > | null }
* /
static monitorResponseTime = null ;
/ * *
* Metric : monitor _status
* @ type { PrometheusClient . Gauge < string > | null }
* /
static monitorStatus = null ;
/ * *
* All registered metric labels .
* @ type { string [ ] | null }
* /
static monitorLabelNames = null ;
/ * *
* Monitor labels / values combination .
* @ type { { } }
* /
monitorLabelValues ;
/ * *
* Initialize metrics and get all label names the first time called .
* @ returns { void }
* /
static async initMetrics ( ) {
if ( ! this . monitorLabelNames ) {
let labelNames = await R . getCol ( "SELECT name FROM tag" ) ;
this . monitorLabelNames = [ ... commonLabels , ... labelNames ] ;
}
if ( ! this . monitorCertDaysRemaining ) {
this . monitorCertDaysRemaining = new PrometheusClient . Gauge ( {
name : "monitor_cert_days_remaining" ,
name : "monitor_cert_days_remaining" ,
help : "The number of days remaining until the certificate expires" ,
help : "The number of days remaining until the certificate expires" ,
labelNames : this . monitorLabelNames
labelNames : commonLabels
} ) ;
} ) ;
}
if ( ! this . monitorCertIsValid ) {
const monitorCertIsValid = new PrometheusClient . Gauge ( {
this . monitorCertIsValid = new PrometheusClient . Gauge ( {
name : "monitor_cert_is_valid" ,
name : "monitor_cert_is_valid" ,
help : "Is the certificate still valid? (1 = Yes, 0 = No)" ,
help : "Is the certificate still valid? (1 = Yes, 0= No)" ,
labelNames : this . monitorLabelNames
labelNames : commonLabels
} ) ;
} ) ;
}
const monitorResponseTime = new PrometheusClient . Gauge ( {
if ( ! this . monitorResponseTime ) {
this . monitorResponseTime = new PrometheusClient . Gauge ( {
name : "monitor_response_time" ,
name : "monitor_response_time" ,
help : "Monitor Response Time (ms)" ,
help : "Monitor Response Time (ms)" ,
labelNames : this . monitorLabelNames
labelNames : commonLabels
} ) ;
} ) ;
}
if ( ! this . monitorStatus ) {
const monitorStatus = new PrometheusClient . Gauge ( {
this . monitorStatus = new PrometheusClient . Gauge ( {
name : "monitor_status" ,
name : "monitor_status" ,
help : "Monitor Status (1 = UP, 0 = DOWN, 2 = PENDING, 3 = MAINTENANCE)" ,
help : "Monitor Status (1 = UP, 0= DOWN, 2= PENDING, 3= MAINTENANCE)" ,
labelNames : this . monitorLabelNames
labelNames : commonLabels
} ) ;
} ) ;
}
}
/ * *
class Prometheus {
* Wrapper to create a ` Prometheus ` instance and ensure metrics are initialized .
monitorLabelValues = { } ;
* @ param { Monitor } monitor Monitor object to monitor
* @ returns { Promise < Prometheus > } ` Prometheus ` instance
* /
static async createAndInitMetrics ( monitor ) {
await Prometheus . initMetrics ( ) ;
let tags = await monitor . getTags ( ) ;
return new Prometheus ( monitor , tags ) ;
}
/ * *
/ * *
* Creates a prometheus metric instance .
* @ param { object } monitor Monitor object to monitor
*
* Note : Make sure to call ` Prometheus.initMetrics() ` once prior creating Prometheus instances .
* @ param { Monitor } monitor Monitor object to monitor
* @ param { Promise < LooseObject < any > [ ] > } tags Tags of the monitor
* /
* /
constructor ( monitor , tags ) {
constructor ( monitor ) {
this . monitorLabelValues = {
this . monitorLabelValues = {
monitor _name : monitor . name ,
monitor _name : monitor . name ,
monitor _type : monitor . type ,
monitor _type : monitor . type ,
@ -113,12 +46,6 @@ class Prometheus {
monitor _hostname : monitor . hostname ,
monitor _hostname : monitor . hostname ,
monitor _port : monitor . port
monitor _port : monitor . port
} ;
} ;
Object . values ( tags )
// only label names that were known at first metric creation.
. filter ( tag => Prometheus . monitorLabelNames . includes ( tag . name ) )
. forEach ( tag => {
this . monitorLabelValues [ tag . name ] = tag . value ;
} ) ;
}
}
/ * *
/ * *
@ -128,6 +55,7 @@ class Prometheus {
* @ returns { void }
* @ returns { void }
* /
* /
update ( heartbeat , tlsInfo ) {
update ( heartbeat , tlsInfo ) {
if ( typeof tlsInfo !== "undefined" ) {
if ( typeof tlsInfo !== "undefined" ) {
try {
try {
let isValid ;
let isValid ;
@ -136,7 +64,7 @@ class Prometheus {
} else {
} else {
isValid = 0 ;
isValid = 0 ;
}
}
Prometheus. monitorCertIsValid. set ( this . monitorLabelValues , isValid ) ;
monitorCertIsValid. set ( this . monitorLabelValues , isValid ) ;
} catch ( e ) {
} catch ( e ) {
log . error ( "prometheus" , "Caught error" ) ;
log . error ( "prometheus" , "Caught error" ) ;
log . error ( "prometheus" , e ) ;
log . error ( "prometheus" , e ) ;
@ -144,7 +72,7 @@ class Prometheus {
try {
try {
if ( tlsInfo . certInfo != null ) {
if ( tlsInfo . certInfo != null ) {
Prometheus. monitorCertDaysRemaining. set ( this . monitorLabelValues , tlsInfo . certInfo . daysRemaining ) ;
monitorCertDaysRemaining. set ( this . monitorLabelValues , tlsInfo . certInfo . daysRemaining ) ;
}
}
} catch ( e ) {
} catch ( e ) {
log . error ( "prometheus" , "Caught error" ) ;
log . error ( "prometheus" , "Caught error" ) ;
@ -154,7 +82,7 @@ class Prometheus {
if ( heartbeat ) {
if ( heartbeat ) {
try {
try {
Prometheus. monitorStatus. set ( this . monitorLabelValues , heartbeat . status ) ;
monitorStatus. set ( this . monitorLabelValues , heartbeat . status ) ;
} catch ( e ) {
} catch ( e ) {
log . error ( "prometheus" , "Caught error" ) ;
log . error ( "prometheus" , "Caught error" ) ;
log . error ( "prometheus" , e ) ;
log . error ( "prometheus" , e ) ;
@ -162,10 +90,10 @@ class Prometheus {
try {
try {
if ( typeof heartbeat . ping === "number" ) {
if ( typeof heartbeat . ping === "number" ) {
Prometheus. monitorResponseTime. set ( this . monitorLabelValues , heartbeat . ping ) ;
monitorResponseTime. set ( this . monitorLabelValues , heartbeat . ping ) ;
} else {
} else {
// Is it good?
// Is it good?
Prometheus. monitorResponseTime. set ( this . monitorLabelValues , - 1 ) ;
monitorResponseTime. set ( this . monitorLabelValues , - 1 ) ;
}
}
} catch ( e ) {
} catch ( e ) {
log . error ( "prometheus" , "Caught error" ) ;
log . error ( "prometheus" , "Caught error" ) ;
@ -180,10 +108,10 @@ class Prometheus {
* /
* /
remove ( ) {
remove ( ) {
try {
try {
Prometheus. monitorCertDaysRemaining? . remove ( this . monitorLabelValues ) ;
monitorCertDaysRemaining. remove ( this . monitorLabelValues ) ;
Prometheus. monitorCertIsValid? . remove ( this . monitorLabelValues ) ;
monitorCertIsValid. remove ( this . monitorLabelValues ) ;
Prometheus. monitorResponseTime? . remove ( this . monitorLabelValues ) ;
monitorResponseTime. remove ( this . monitorLabelValues ) ;
Prometheus. monitorStatus? . remove ( this . monitorLabelValues ) ;
monitorStatus. remove ( this . monitorLabelValues ) ;
} catch ( e ) {
} catch ( e ) {
console . error ( e ) ;
console . error ( e ) ;
}
}