@data-fair/lib-node 2.8.1 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/axios-auth.js CHANGED
@@ -1,69 +1,81 @@
1
1
  // build axios instances with sessions on a simple-directory instance
2
2
  // WARNING: use for integration testing only
3
- import { Agent } from 'node:http'
4
- import { axiosBuilder, axiosInstance } from './axios.js'
5
- import { CookieJar } from 'tough-cookie'
3
+ import { Agent } from 'node:http';
4
+ import { axiosBuilder, axiosInstance } from './axios.js';
5
+ import { CookieJar } from 'tough-cookie';
6
6
  const getConfigUrl = (config) => {
7
- if (!config.url) { throw new Error('url is required') }
8
- return new URL((config.baseURL && config.url?.startsWith('/')) ? (config.baseURL + config.url) : config.url)
7
+ if (!config.url)
8
+ throw new Error('url is required');
9
+ return new URL((config.baseURL && config.url?.startsWith('/')) ? (config.baseURL + config.url) : config.url);
10
+ };
11
+ export async function axiosAuth(opts) {
12
+ const body = { email: opts.email, password: opts.password };
13
+ if (opts.org)
14
+ body.org = opts.org;
15
+ if (opts.dep)
16
+ body.dep = opts.dep;
17
+ if (opts.adminMode)
18
+ body.adminMode = opts.adminMode;
19
+ if (opts.orgStorage)
20
+ body.orgStorage = opts.orgStorage;
21
+ const axiosOpts = {
22
+ httpAgent: new Agent({ keepAlive: false }),
23
+ maxRedirects: 0,
24
+ ...opts.axiosOpts
25
+ };
26
+ const directoryUrl = opts.directoryUrl ?? 'http://localhost:8080';
27
+ let callbackUrl = (await axiosInstance.post(directoryUrl + '/api/auth/password', body, { params: { redirect: directoryUrl }, maxRedirects: 0 })).data;
28
+ if (callbackUrl.startsWith(directoryUrl + '/simple-directory')) {
29
+ callbackUrl = callbackUrl.replace(directoryUrl + '/simple-directory', directoryUrl);
30
+ }
31
+ const cookieJar = new CookieJar();
32
+ const sdOrigin = new URL(directoryUrl).origin;
33
+ try {
34
+ await axiosInstance.get(callbackUrl, { maxRedirects: 0 });
35
+ }
36
+ catch (err) {
37
+ if (err.status !== 302)
38
+ throw err;
39
+ const redirectUrl = new URL(err.headers.location);
40
+ const redirectError = redirectUrl.searchParams.get('error');
41
+ if (redirectError)
42
+ throw new Error(redirectError);
43
+ for (const cookie of err.headers['set-cookie'] ?? [])
44
+ cookieJar.setCookieSync(cookie, sdOrigin);
45
+ }
46
+ const ax = axiosBuilder(axiosOpts, (ax) => {
47
+ ax.interceptors.request.use((config) => {
48
+ const url = getConfigUrl(config);
49
+ // if opts.globalCookies is true the cookie jar is used to store cookies shared accross all domains
50
+ // this behavior is useful for testing purposes if serves are not on the same domain
51
+ if (!opts.globalCookies || url.origin === sdOrigin) {
52
+ config.headers.Cookie = cookieJar.getCookiesSync(url.href);
53
+ }
54
+ else {
55
+ config.headers.Cookie = cookieJar.getCookiesSync(sdOrigin);
56
+ }
57
+ return config;
58
+ });
59
+ ax.interceptors.response.use((res) => {
60
+ const origin = opts.globalCookies ? sdOrigin : getConfigUrl(res.config).origin;
61
+ for (const cookie of res.headers['set-cookie'] ?? [])
62
+ cookieJar.setCookieSync(cookie, origin);
63
+ return res;
64
+ }, async (error) => {
65
+ const res = error.response;
66
+ if (res) {
67
+ const origin = opts.globalCookies ? sdOrigin : getConfigUrl(res.config).origin;
68
+ for (const cookie of res.headers['set-cookie'] ?? [])
69
+ cookieJar.setCookieSync(cookie, origin);
70
+ }
71
+ return Promise.reject(error);
72
+ });
73
+ });
74
+ ax.cookieJar = cookieJar;
75
+ ax.setOrg = (org, dep) => {
76
+ cookieJar.setCookieSync(`id_token_org=${org}`, sdOrigin);
77
+ cookieJar.setCookieSync(`id_token_dep=${dep ?? ''}`, sdOrigin);
78
+ };
79
+ return ax;
9
80
  }
10
- export async function axiosAuth (opts) {
11
- const body = { email: opts.email, password: opts.password }
12
- if (opts.org) { body.org = opts.org }
13
- if (opts.dep) { body.dep = opts.dep }
14
- if (opts.adminMode) { body.adminMode = opts.adminMode }
15
- if (opts.orgStorage) { body.orgStorage = opts.orgStorage }
16
- const axiosOpts = {
17
- httpAgent: new Agent({ keepAlive: false }),
18
- maxRedirects: 0,
19
- ...opts.axiosOpts
20
- }
21
- const directoryUrl = opts.directoryUrl ?? 'http://localhost:8080'
22
- let callbackUrl = (await axiosInstance.post(directoryUrl + '/api/auth/password', body, { params: { redirect: directoryUrl }, maxRedirects: 0 })).data
23
- if (callbackUrl.startsWith(directoryUrl + '/simple-directory')) {
24
- callbackUrl = callbackUrl.replace(directoryUrl + '/simple-directory', directoryUrl)
25
- }
26
- const cookieJar = new CookieJar()
27
- const sdOrigin = new URL(directoryUrl).origin
28
- try {
29
- await axiosInstance.get(callbackUrl, { maxRedirects: 0 })
30
- } catch (err) {
31
- if (err.status !== 302) { throw err }
32
- const redirectUrl = new URL(err.headers.location)
33
- const redirectError = redirectUrl.searchParams.get('error')
34
- if (redirectError) { throw new Error(redirectError) }
35
- for (const cookie of err.headers['set-cookie'] ?? []) { cookieJar.setCookieSync(cookie, sdOrigin) }
36
- }
37
- const ax = axiosBuilder(axiosOpts, (ax) => {
38
- ax.interceptors.request.use((config) => {
39
- const url = getConfigUrl(config)
40
- // if opts.globalCookies is true the cookie jar is used to store cookies shared accross all domains
41
- // this behavior is useful for testing purposes if serves are not on the same domain
42
- if (!opts.globalCookies || url.origin === sdOrigin) {
43
- config.headers.Cookie = cookieJar.getCookiesSync(url.href)
44
- } else {
45
- config.headers.Cookie = cookieJar.getCookiesSync(sdOrigin)
46
- }
47
- return config
48
- })
49
- ax.interceptors.response.use((res) => {
50
- const origin = opts.globalCookies ? sdOrigin : getConfigUrl(res.config).origin
51
- for (const cookie of res.headers['set-cookie'] ?? []) { cookieJar.setCookieSync(cookie, origin) }
52
- return res
53
- }, async (error) => {
54
- const res = error.response
55
- if (res) {
56
- const origin = opts.globalCookies ? sdOrigin : getConfigUrl(res.config).origin
57
- for (const cookie of res.headers['set-cookie'] ?? []) { cookieJar.setCookieSync(cookie, origin) }
58
- }
59
- return Promise.reject(error)
60
- })
61
- })
62
- ax.cookieJar = cookieJar
63
- ax.setOrg = (org, dep) => {
64
- cookieJar.setCookieSync(`id_token_org=${org}`, sdOrigin)
65
- cookieJar.setCookieSync(`id_token_dep=${dep ?? ''}`, sdOrigin)
66
- }
67
- return ax
68
- }
69
- export default axiosAuth
81
+ export default axiosAuth;
package/axios.js CHANGED
@@ -1,51 +1,55 @@
1
1
  // prepare an axios instance with improved error management and some performance tuning for nodejs usage
2
- import axios from 'axios'
3
- import { httpAgent, httpsAgent } from './http-agents.js'
4
- const { stackTraceLimit } = Error
2
+ import axios from 'axios';
3
+ import { httpAgent, httpsAgent } from './http-agents.js';
4
+ const { stackTraceLimit } = Error;
5
5
  class AxiosRequestError extends Error {
6
- constructor () {
7
- super()
8
- this.name = 'AxiosRequestError'
9
- }
6
+ constructor() {
7
+ super();
8
+ this.name = 'AxiosRequestError';
9
+ }
10
10
  }
11
11
  const requestInterceptor = (config) => {
12
- // better stack traces
13
- // see https://github.com/axios/axios/issues/2387#issuecomment-652242713
14
- Error.stackTraceLimit = 0
15
- const errorContext = new AxiosRequestError()
16
- Error.stackTraceLimit = stackTraceLimit
17
- Error.captureStackTrace(errorContext, requestInterceptor)
18
- // @ts-ignore
19
- config.errorContext = errorContext
20
- return config
21
- }
22
- export function axiosBuilder (opts = {}, beforeInterceptors) {
23
- const ax = axios.create({
24
- httpAgent,
25
- httpsAgent,
26
- ...opts
27
- })
28
- if (beforeInterceptors) { beforeInterceptors(ax) }
29
- ax.interceptors.request.use(requestInterceptor)
30
- // shorter stack traces
31
- ax.interceptors.response.use(response => response, error => {
32
- if (!error.response) {
33
- if (error.config?.errorContext?.stack) { error.stack += '\nRequest context:\n' + error.config?.errorContext?.stack }
34
- return Promise.reject(error)
35
- }
36
- delete error.response.request
37
- error.response.config = { method: error.response.config.method, url: error.response.config.url, data: error.response.config.data }
38
- if (error.response.config.data && error.response.config.data._writableState) { delete error.response.config.data }
39
- if (error.response.data && error.response.data._readableState) { delete error.response.data }
40
- let messageText = error.response.statusText
41
- if (error.response.data) {
42
- messageText = typeof error.response.data === 'string' ? error.response.data : JSON.stringify(error.response.data)
43
- }
44
- error.response.message = `${error.response.status} - ${messageText}`
45
- Object.assign(error.config.errorContext, error.response)
46
- return Promise.reject(error.config.errorContext)
47
- })
48
- return ax
12
+ // better stack traces
13
+ // see https://github.com/axios/axios/issues/2387#issuecomment-652242713
14
+ Error.stackTraceLimit = 0;
15
+ const errorContext = new AxiosRequestError();
16
+ Error.stackTraceLimit = stackTraceLimit;
17
+ Error.captureStackTrace(errorContext, requestInterceptor);
18
+ // @ts-ignore
19
+ config.errorContext = errorContext;
20
+ return config;
21
+ };
22
+ export function axiosBuilder(opts = {}, beforeInterceptors) {
23
+ const ax = axios.create({
24
+ httpAgent,
25
+ httpsAgent,
26
+ ...opts
27
+ });
28
+ if (beforeInterceptors)
29
+ beforeInterceptors(ax);
30
+ ax.interceptors.request.use(requestInterceptor);
31
+ // shorter stack traces
32
+ ax.interceptors.response.use(response => response, error => {
33
+ if (!error.response) {
34
+ if (error.config?.errorContext?.stack)
35
+ error.stack += '\nRequest context:\n' + error.config?.errorContext?.stack;
36
+ return Promise.reject(error);
37
+ }
38
+ delete error.response.request;
39
+ error.response.config = { method: error.response.config.method, url: error.response.config.url, data: error.response.config.data };
40
+ if (error.response.config.data && error.response.config.data._writableState)
41
+ delete error.response.config.data;
42
+ if (error.response.data && error.response.data._readableState)
43
+ delete error.response.data;
44
+ let messageText = error.response.statusText;
45
+ if (error.response.data) {
46
+ messageText = typeof error.response.data === 'string' ? error.response.data : JSON.stringify(error.response.data);
47
+ }
48
+ error.response.message = `${error.response.status} - ${messageText}`;
49
+ Object.assign(error.config.errorContext, error.response);
50
+ return Promise.reject(error.config.errorContext);
51
+ });
52
+ return ax;
49
53
  }
50
- export const axiosInstance = axiosBuilder()
51
- export default axiosInstance
54
+ export const axiosInstance = axiosBuilder();
55
+ export default axiosInstance;
package/events-queue.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import { type Event } from '@data-fair/lib-common-types/event/index.js';
2
2
  import { type Notification } from '@data-fair/lib-common-types/notification/index.js';
3
3
  import { SessionState } from '@data-fair/lib-common-types/session/index.js';
4
- type EventsQueueOptions = {
4
+ export type EventsQueueOptions = {
5
5
  eventsUrl: string;
6
6
  eventsSecret: string;
7
7
  inactive?: boolean;
8
8
  };
9
+ export type PushEvent = Omit<Event, 'date'>;
10
+ export type PushNotification = Omit<Notification, 'date'>;
9
11
  export declare class EventsQueue {
10
12
  _options: EventsQueueOptions | undefined;
11
13
  eventsQueue: Event[];
@@ -17,8 +19,8 @@ export declare class EventsQueue {
17
19
  stop: () => Promise<void>;
18
20
  loop(): Promise<void>;
19
21
  drain(): Promise<void>;
20
- pushEvent(event: Omit<Event, 'date'>, sessionState?: SessionState): void;
21
- pushNotification(notification: Omit<Notification, 'date'>): void;
22
+ pushEvent(event: PushEvent, sessionState?: SessionState): void;
23
+ pushNotification(notification: PushNotification): void;
22
24
  }
23
25
  declare const eventsQueue: EventsQueue;
24
26
  export default eventsQueue;
package/events-queue.js CHANGED
@@ -1,110 +1,116 @@
1
- import { internalError } from '@data-fair/lib-node/observer.js'
2
- import axios from './axios.js'
3
- import Debug from 'debug'
4
- const debug = Debug('events-queue')
1
+ import { internalError } from '@data-fair/lib-node/observer.js';
2
+ import axios from './axios.js';
3
+ import Debug from 'debug';
4
+ const debug = Debug('events-queue');
5
5
  export class EventsQueue {
6
- _options
7
- eventsQueue = []
8
- notificationsQueue = []
9
- stopped = false
10
- currentDrainPromise
11
- options () {
12
- if (!this._options) { throw new Error('events queue was not initialized') }
13
- return this._options
14
- }
15
-
16
- start = async (options) => {
17
- if (this._options) { throw new Error('events queue was already initialized') }
18
- this._options = options
19
- this.loop()
20
- }
21
-
22
- stop = async () => {
23
- this.stopped = true
24
- if (this.currentDrainPromise) { await this.currentDrainPromise }
25
- await this.drain()
26
- }
27
-
28
- async loop () {
29
- while (!this.stopped) {
30
- await new Promise(resolve => setTimeout(resolve, 3000))
31
- this.currentDrainPromise = this.drain()
32
- await this.currentDrainPromise
33
- this.currentDrainPromise = undefined
6
+ _options;
7
+ eventsQueue = [];
8
+ notificationsQueue = [];
9
+ stopped = false;
10
+ currentDrainPromise;
11
+ options() {
12
+ if (!this._options)
13
+ throw new Error('events queue was not initialized');
14
+ return this._options;
34
15
  }
35
- }
36
-
37
- async drain () {
38
- if (this.eventsQueue.length) {
39
- const events = this.eventsQueue
40
- this.eventsQueue = []
41
- debug('drain events', events.length)
42
- try {
43
- await axios.post(this.options().eventsUrl + '/api/events', events, { headers: { 'x-secret-key': this.options().eventsSecret } })
44
- } catch (err) {
45
- internalError('events-queue-push-event', err)
46
- // retry later
47
- if (err.status >= 500 && events.length < 1000) { this.eventsQueue = events.concat(this.eventsQueue) }
48
- }
49
- }
50
- if (this.notificationsQueue.length) {
51
- const notifications = this.notificationsQueue
52
- this.notificationsQueue = []
53
- debug('drain notifications', notifications.length)
54
- for (const notification of notifications) {
55
- try {
56
- await axios.post(this.options().eventsUrl + '/api/notifications', notification, { headers: { 'x-secret-key': this.options().eventsSecret } })
57
- } catch (err) {
58
- internalError('events-queue-push-notif', err)
59
- // retry later
60
- if (err.status >= 500 && (notifications.length + this.notificationsQueue.length) < 1000) {
61
- this.notificationsQueue.unshift()
62
- }
16
+ start = async (options) => {
17
+ if (this._options)
18
+ throw new Error('events queue was already initialized');
19
+ this._options = options;
20
+ this.loop();
21
+ };
22
+ stop = async () => {
23
+ this.stopped = true;
24
+ if (this.currentDrainPromise)
25
+ await this.currentDrainPromise;
26
+ await this.drain();
27
+ };
28
+ async loop() {
29
+ while (!this.stopped) {
30
+ await new Promise(resolve => setTimeout(resolve, 3000));
31
+ this.currentDrainPromise = this.drain();
32
+ await this.currentDrainPromise;
33
+ this.currentDrainPromise = undefined;
63
34
  }
64
- }
65
35
  }
66
- }
67
-
68
- pushEvent (event, sessionState) {
69
- const options = this.options()
70
- if (options.inactive) { return }
71
- if (this.stopped) { throw new Error('events queue has been stopped') }
72
- event.date = new Date().toISOString()
73
- debug('pushEvent', event)
74
- if (!event.originator && sessionState?.user && sessionState.account) {
75
- if (sessionState.user.asAdmin) {
76
- event.originator = {
77
- user: { ...sessionState.user.asAdmin, admin: true }
78
- }
79
- } else if (sessionState.user.adminMode && (sessionState.account.type !== event.sender?.type || sessionState.account.id !== event.sender?.id)) {
80
- event.originator = {
81
- user: { id: sessionState.user.id, name: sessionState.user.name, admin: true }
36
+ async drain() {
37
+ if (this.eventsQueue.length) {
38
+ const events = this.eventsQueue;
39
+ this.eventsQueue = [];
40
+ debug('drain events', events.length);
41
+ try {
42
+ await axios.post(this.options().eventsUrl + '/api/events', events, { headers: { 'x-secret-key': this.options().eventsSecret } });
43
+ }
44
+ catch (err) {
45
+ internalError('events-queue-push-event', err);
46
+ // retry later
47
+ if (err.status >= 500 && events.length < 1000)
48
+ this.eventsQueue = events.concat(this.eventsQueue);
49
+ }
82
50
  }
83
- } else {
84
- event.originator = {
85
- user: { id: sessionState.user.id, name: sessionState.user.name }
51
+ if (this.notificationsQueue.length) {
52
+ const notifications = this.notificationsQueue;
53
+ this.notificationsQueue = [];
54
+ debug('drain notifications', notifications.length);
55
+ for (const notification of notifications) {
56
+ try {
57
+ await axios.post(this.options().eventsUrl + '/api/notifications', notification, { headers: { 'x-secret-key': this.options().eventsSecret } });
58
+ }
59
+ catch (err) {
60
+ internalError('events-queue-push-notif', err);
61
+ // retry later
62
+ if (err.status >= 500 && (notifications.length + this.notificationsQueue.length) < 1000) {
63
+ this.notificationsQueue.unshift();
64
+ }
65
+ }
66
+ }
86
67
  }
87
- if (sessionState.organization) {
88
- event.originator.organization = {
89
- id: sessionState.organization.id,
90
- name: sessionState.organization.name,
91
- department: sessionState.organization.department,
92
- departmentName: sessionState.organization.departmentName
93
- }
68
+ }
69
+ pushEvent(event, sessionState) {
70
+ const options = this.options();
71
+ if (options.inactive)
72
+ return;
73
+ if (this.stopped)
74
+ throw new Error('events queue has been stopped');
75
+ event.date = new Date().toISOString();
76
+ debug('pushEvent', event);
77
+ if (!event.originator && sessionState?.user && sessionState.account) {
78
+ if (sessionState.user.asAdmin) {
79
+ event.originator = {
80
+ user: { ...sessionState.user.asAdmin, admin: true }
81
+ };
82
+ }
83
+ else if (sessionState.user.adminMode && (sessionState.account.type !== event.sender?.type || sessionState.account.id !== event.sender?.id)) {
84
+ event.originator = {
85
+ user: { id: sessionState.user.id, name: sessionState.user.name, admin: true }
86
+ };
87
+ }
88
+ else {
89
+ event.originator = {
90
+ user: { id: sessionState.user.id, name: sessionState.user.name }
91
+ };
92
+ if (sessionState.organization) {
93
+ event.originator.organization = {
94
+ id: sessionState.organization.id,
95
+ name: sessionState.organization.name,
96
+ department: sessionState.organization.department,
97
+ departmentName: sessionState.organization.departmentName
98
+ };
99
+ }
100
+ }
94
101
  }
95
- }
102
+ this.eventsQueue.push(event);
103
+ }
104
+ pushNotification(notification) {
105
+ const options = this.options();
106
+ if (options.inactive)
107
+ return;
108
+ if (this.stopped)
109
+ throw new Error('notifications queue has been stopped');
110
+ notification.date = new Date().toISOString();
111
+ debug('pushNotification', notification);
112
+ this.notificationsQueue.push(notification);
96
113
  }
97
- this.eventsQueue.push(event)
98
- }
99
-
100
- pushNotification (notification) {
101
- const options = this.options()
102
- if (options.inactive) { return }
103
- if (this.stopped) { throw new Error('notifications queue has been stopped') }
104
- notification.date = new Date().toISOString()
105
- debug('pushNotification', notification)
106
- this.notificationsQueue.push(notification)
107
- }
108
114
  }
109
- const eventsQueue = new EventsQueue()
110
- export default eventsQueue
115
+ const eventsQueue = new EventsQueue();
116
+ export default eventsQueue;
package/http-agents.js CHANGED
@@ -1,55 +1,55 @@
1
1
  // use better DNS lookup than nodejs default and try to reduce number of socket openings
2
- import CacheableLookup from 'cacheable-lookup'
3
- import HttpAgent, { HttpsAgent } from 'agentkeepalive'
4
- import { Counter, Gauge } from 'prom-client'
2
+ import CacheableLookup from 'cacheable-lookup';
3
+ import HttpAgent, { HttpsAgent } from 'agentkeepalive';
4
+ import { Counter, Gauge } from 'prom-client';
5
5
  // not very high number of sockets but we don't want to saturate our reverse proxies
6
6
  // if a higher number is needed the service should probably be scaled anyway
7
7
  const keepaliveOpts = {
8
- maxSockets: 8,
9
- maxFreeSockets: 8,
10
- timeout: 60000,
11
- freeSocketTimeout: 30000
12
- }
13
- export const httpAgent = new HttpAgent(keepaliveOpts)
14
- export const httpsAgent = new HttpsAgent(keepaliveOpts)
15
- const cacheableLookup = new CacheableLookup()
16
- cacheableLookup.install(httpAgent)
17
- cacheableLookup.install(httpsAgent)
8
+ maxSockets: 8,
9
+ maxFreeSockets: 8,
10
+ timeout: 60000,
11
+ freeSocketTimeout: 30000
12
+ };
13
+ export const httpAgent = new HttpAgent(keepaliveOpts);
14
+ export const httpsAgent = new HttpsAgent(keepaliveOpts);
15
+ const cacheableLookup = new CacheableLookup();
16
+ cacheableLookup.install(httpAgent);
17
+ cacheableLookup.install(httpsAgent);
18
18
  // monitor agent statuses
19
- const agents = { http: httpAgent, https: httpsAgent }
19
+ const agents = { http: httpAgent, https: httpsAgent };
20
20
  const socketsGauge = new Gauge({
21
- name: 'df_http_agent_sockets',
22
- help: 'Number of open sockets in the http agent',
23
- labelNames: ['protocol', 'host']
24
- })
21
+ name: 'df_http_agent_sockets',
22
+ help: 'Number of open sockets in the http agent',
23
+ labelNames: ['protocol', 'host']
24
+ });
25
25
  const freeSocketsGauge = new Gauge({
26
- name: 'df_http_agent_free_sockets',
27
- help: 'Number of free sockets in the http agent',
28
- labelNames: ['protocol', 'host']
29
- })
26
+ name: 'df_http_agent_free_sockets',
27
+ help: 'Number of free sockets in the http agent',
28
+ labelNames: ['protocol', 'host']
29
+ });
30
30
  const createSocketCounter = new Counter({
31
- name: 'df_http_agent_create_socket_total',
32
- help: 'Total number of sockets created by the http agent',
33
- labelNames: ['protocol']
34
- })
31
+ name: 'df_http_agent_create_socket_total',
32
+ help: 'Total number of sockets created by the http agent',
33
+ labelNames: ['protocol']
34
+ });
35
35
  const requestCounter = new Counter({
36
- name: 'df_http_agent_request_total',
37
- help: 'Total number of requests created by the http agent',
38
- labelNames: ['protocol']
39
- })
36
+ name: 'df_http_agent_request_total',
37
+ help: 'Total number of requests created by the http agent',
38
+ labelNames: ['protocol']
39
+ });
40
40
  setInterval(() => {
41
- for (const _protocol of ['http', 'https']) {
42
- const protocol = _protocol
43
- const agentStatus = agents[protocol].getCurrentStatus()
44
- for (const host in agentStatus.sockets) {
45
- socketsGauge.set({ protocol, host }, agentStatus.sockets[host])
41
+ for (const _protocol of ['http', 'https']) {
42
+ const protocol = _protocol;
43
+ const agentStatus = agents[protocol].getCurrentStatus();
44
+ for (const host in agentStatus.sockets) {
45
+ socketsGauge.set({ protocol, host }, agentStatus.sockets[host]);
46
+ }
47
+ for (const host in agentStatus.freeSockets) {
48
+ freeSocketsGauge.set({ protocol, host }, agentStatus.freeSockets[host]);
49
+ }
50
+ createSocketCounter.remove({ protocol });
51
+ createSocketCounter.inc({ protocol }, agentStatus.createSocketCount);
52
+ requestCounter.remove({ protocol });
53
+ requestCounter.inc({ protocol }, agentStatus.requestCount);
46
54
  }
47
- for (const host in agentStatus.freeSockets) {
48
- freeSocketsGauge.set({ protocol, host }, agentStatus.freeSockets[host])
49
- }
50
- createSocketCounter.remove({ protocol })
51
- createSocketCounter.inc({ protocol }, agentStatus.createSocketCount)
52
- requestCounter.remove({ protocol })
53
- requestCounter.inc({ protocol }, agentStatus.requestCount)
54
- }
55
- }, 60000)
55
+ }, 60000);