UNPKG

@sourceregistry/node-prometheus

Version:

A lightweight, zero-dependency TypeScript library for creating and exposing Prometheus metrics in standard exposition and OpenMetrics format.

19 lines (18 loc) 3.72 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class n{constructor(t,e,r,s){this.type=t,this.name=n.cleanText(e)||"",this.description=r,this.labels=s}static labelString(t){return!t||Object.keys(t).length===0?"":`{${Object.entries(t).map(([e,r])=>`${e}="${String(r)}"`).join(",")}}`}static cleanText(t){return t?.replaceAll("-","").replaceAll("/","_").replaceAll(" ","_").replaceAll("(","").replaceAll(")","")}static async concat(t="prometheus",...e){let s=(await Promise.all(e.map(u=>u.stringify()))).join(` `);return t==="openmetrics"&&(s=s.trimEnd()+` # EOF`),s}generateHeader(){let t="";return this.name&&this.description&&(t+=`# HELP ${this.name} ${this.description} `),this.type!=="untyped"&&(t+=`# TYPE ${this.name} ${this.type} `),t}}class a extends n{constructor(t,e){super(t,e.name,e.description,e.labels),this._reader=async()=>(await e.reader()).map(s=>{if(typeof s=="number")return[s,{},Date.now()];if(Array.isArray(s))return s.length===2?typeof s[1]=="number"?[s[0],{},s[1]]:[s[0],s[1],Date.now()]:s;throw new Error(`Unexpected value format: ${JSON.stringify(s)}`)})}async valueString(){return(await this._reader()).map(([e,r,s])=>`${this.name}${n.labelString({...this.labels,...r})} ${e} ${s} `).join("")}async stringify(){return`${super.generateHeader()}${await this.valueString()} `}}class l extends a{constructor(t){super("gauge",t)}}class c extends a{constructor(t){super("counter",t)}inc(t=1){console.warn(`Counter.inc() called, but Counter uses reader function. Increment must be handled externally. Delta: ${t}`)}}class h extends n{constructor(t){super("histogram",t.name,t.description,t.labels),this._bucketCounts={},this._sum=0,this._count=0;const e=(t.buckets??[]).sort((r,s)=>r-s);this._buckets=[...e,1/0],this.reset()}reset(){this._buckets.forEach(t=>this._bucketCounts[t]=0),this._sum=0,this._count=0}observe(t){if(typeof t!="number"||isNaN(t))throw new Error(`Invalid histogram value: ${t}`);this.push(t)}push(t){this._sum+=t,this._count++;for(const e of this._buckets)t<=e&&this._bucketCounts[e]++}bucketString(){return`${this._buckets.map(e=>{const r=e===1/0?"+Inf":e;return`${this.name}_bucket${n.labelString({...this.labels,le:r})} ${this._bucketCounts[e]}`}).join(` `)} ${this.name}_sum ${this._sum} ${this.name}_count ${this._count}`}async stringify(){return`${super.generateHeader()}${this.bucketString()} `}}class o extends n{constructor(t){if(super("summary",t.name,t.description),this._sum=0,this._count=0,!t.quantiles.length)throw new Error("Summary must have at least one quantile");this._quantiles=new Map(t.quantiles.map(e=>[e,0])),this._calculate=t.calculate}observe(t){if(typeof t!="number"||isNaN(t))throw new Error(`Invalid summary value: ${t}`);this.push(t)}push(t){this._sum+=t,this._count++,this._quantiles.forEach((e,r)=>{const s=this._calculate(t,r);this._quantiles.set(r,s)})}summaryString(){return`${[...this._quantiles.entries()].sort(([e],[r])=>e-r).map(([e,r])=>`${this.name}${n.labelString({...this.labels,quantile:e})} ${r}`).join(` `)} ${this.name}_sum ${this._sum} ${this.name}_count ${this._count}`}async stringify(){return`${super.generateHeader()}${this.summaryString()} `}}class m extends n{constructor(t){super("untyped",t.name,t.description,t.labels),this._value=Array.isArray(t.value)?t.value:[t.value??0,Date.now()]}set(t){this._value=Array.isArray(t)?t:[t,Date.now()]}get(){return this._value}valueString(){return`${this.name}${n.labelString(this.labels)} ${this._value[0]} ${this._value[1]} `}async stringify(){return`${super.generateHeader()}${this.valueString()} `}}exports.Counter=c;exports.Gauge=l;exports.Histogram=h;exports.Metric=n;exports.Summary=o;exports.Untyped=m; //# sourceMappingURL=index.cjs.js.map