@spinajs/log-source-graphana-loki 2.0.481 → 2.0.482

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.
@@ -1,9 +1,31 @@
1
1
  import { IInstanceCheck } from "@spinajs/di";
2
- import { Log, ILogEntry, LogTarget, ICommonTargetOptions } from "@spinajs/log";
3
- import { Axios } from "axios";
2
+ import { Log, ILogEntry, LogTarget, ICommonTargetOptions, BatchQueue } from "@spinajs/log";
3
+ import { AxiosInstance } from "axios";
4
+ import { ResiliencePipeline } from "@spinajs/util";
5
+ /**
6
+ * Decide whether a failed Loki push is worth retrying.
7
+ *
8
+ * Retryable: any error without an HTTP response ( network / timeout / DNS, eg.
9
+ * ECONNREFUSED / ETIMEDOUT / ECONNRESET / EAI_AGAIN ), or an HTTP response with
10
+ * status 429 / 502 / 503 / 504. Everything else ( 4xx client errors like 400 /
11
+ * 401 / 403 / 404, and any other status ) is treated as a permanent error that
12
+ * must surface rather than loop forever.
13
+ */
14
+ export declare function isRetryableLokiError(error: unknown): boolean;
15
+ /**
16
+ * Read a `Retry-After` header from a Loki error response and return the delay in
17
+ * milliseconds. Supports both the numeric ( delta-seconds ) and HTTP-date forms.
18
+ * Returns `undefined` when there is no usable header.
19
+ */
20
+ export declare function retryAfterMs(error: unknown): number | undefined;
4
21
  export interface IGraphanaOptions extends ICommonTargetOptions {
5
22
  interval: number;
6
23
  bufferSize: number;
24
+ /**
25
+ * Hard cap on the number of entries retained for retry. When a flush fails and the
26
+ * retained + newly buffered entries exceed this, the oldest are dropped.
27
+ */
28
+ maxBufferSize: number;
7
29
  timeout: number;
8
30
  host: string;
9
31
  auth: {
@@ -14,24 +36,38 @@ export interface IGraphanaOptions extends ICommonTargetOptions {
14
36
  app: string;
15
37
  };
16
38
  }
17
- declare enum TargetStatus {
18
- WRITTING = 0,
19
- PENDING = 1,
20
- IDLE = 2
21
- }
22
39
  export declare class GraphanaLokiLogTarget extends LogTarget<IGraphanaOptions> implements IInstanceCheck {
23
40
  protected Log: Log;
24
- protected Entries: ILogEntry[];
25
- protected WriteEntries: ILogEntry[];
26
- protected Status: TargetStatus;
27
- protected FlushTimer: NodeJS.Timeout;
28
- protected AxiosInstance: Axios;
41
+ /**
42
+ * The single buffered-batch queue that owns accumulation, the flush timer and
43
+ * the maxQueue cap. The actual Loki push happens in `send`, wired as its
44
+ * `onFlush`.
45
+ */
46
+ protected Queue: BatchQueue<ILogEntry>;
47
+ /**
48
+ * Set true when the queue overflows maxBufferSize, so the drop warning is
49
+ * emitted ONCE per overflow episode and reset when a flush succeeds.
50
+ */
51
+ protected Overflowed: boolean;
52
+ protected AxiosInstance: AxiosInstance;
53
+ /**
54
+ * Reusable resilience pipeline guarding the Loki push with exponential
55
+ * backoff + jitter, honoring `Retry-After` and only retrying transient errors.
56
+ */
57
+ protected RetryPipeline: ResiliencePipeline<void>;
29
58
  constructor(options: IGraphanaOptions);
30
59
  __checkInstance__(creationOptions: IGraphanaOptions[]): boolean;
31
60
  resolve(): void;
32
61
  write(data: ILogEntry): void;
62
+ forceFlush(): Promise<void>;
33
63
  dispose(): Promise<void>;
34
- protected flush(): void;
64
+ /**
65
+ * Push a single batch to Loki. Wired as the queue's `onFlush`.
66
+ *
67
+ * MUST resolve ( never reject ) so shutdown()/forceFlush() cannot reject: on a
68
+ * retryable-exhausted failure the batch is requeued at the front, on a
69
+ * non-retryable error it is dropped and surfaced via HasError/Error.
70
+ */
71
+ protected send(batch: ILogEntry[]): Promise<void>;
35
72
  }
36
- export {};
37
73
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAgC,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,oBAAoB,EAAU,MAAM,cAAc,CAAC;AAGvF,OAAc,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAGrC,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAE5D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAWD,aAAK,YAAY;IACf,QAAQ,IAAA;IACR,OAAO,IAAA;IACP,IAAI,IAAA;CACL;AAID,qBAEa,qBAAsB,SAAQ,SAAS,CAAC,gBAAgB,CAAE,YAAW,cAAc;IAE9F,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,CAAM;IACpC,SAAS,CAAC,YAAY,EAAE,SAAS,EAAE,CAAM;IAEzC,SAAS,CAAC,MAAM,EAAE,YAAY,CAAqB;IAEnD,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC;IACrC,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC;gBAEnB,OAAO,EAAE,gBAAgB;IAarC,iBAAiB,CAAC,eAAe,EAAE,gBAAgB,EAAE,GAAG,OAAO;IAIxD,OAAO,IAAI,IAAI;IAyBf,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IA2BtB,OAAO;IAWpB,SAAS,CAAC,KAAK;CA8ChB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAgC,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,oBAAoB,EAAU,UAAU,EAAE,MAAM,cAAc,CAAC;AAGnG,OAAc,EAAc,aAAa,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAe,kBAAkB,EAAuC,MAAM,eAAe,CAAC;AAQrG;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAW5D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAwB/D;AAED,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAE5D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAaD,qBAEa,qBAAsB,SAAQ,SAAS,CAAC,gBAAgB,CAAE,YAAW,cAAc;IAE9F,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAEvC;;;OAGG;IACH,SAAS,CAAC,UAAU,UAAS;IAE7B,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IAEvC;;;OAGG;IACH,SAAS,CAAC,aAAa,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAEtC,OAAO,EAAE,gBAAgB;IAoBrC,iBAAiB,CAAC,eAAe,EAAE,gBAAgB,EAAE,GAAG,OAAO;IAIxD,OAAO,IAAI,IAAI;IA8Df,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAY5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,OAAO;IAKpB;;;;;;OAMG;cACa,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAkExD"}
package/lib/cjs/index.js CHANGED
@@ -13,97 +13,174 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.GraphanaLokiLogTarget = void 0;
16
+ exports.isRetryableLokiError = isRetryableLokiError;
17
+ exports.retryAfterMs = retryAfterMs;
16
18
  /* eslint-disable promise/always-return */
17
19
  /* eslint-disable security/detect-object-injection */
18
20
  const configuration_common_1 = require("@spinajs/configuration-common");
19
21
  const di_1 = require("@spinajs/di");
20
22
  const log_1 = require("@spinajs/log");
21
23
  const axios_1 = __importDefault(require("axios"));
22
- var TargetStatus;
23
- (function (TargetStatus) {
24
- TargetStatus[TargetStatus["WRITTING"] = 0] = "WRITTING";
25
- TargetStatus[TargetStatus["PENDING"] = 1] = "PENDING";
26
- TargetStatus[TargetStatus["IDLE"] = 2] = "IDLE";
27
- })(TargetStatus || (TargetStatus = {}));
24
+ const util_1 = require("@spinajs/util");
25
+ /**
26
+ * HTTP status codes worth retrying against Loki: rate limiting and transient
27
+ * upstream / gateway failures.
28
+ */
29
+ const RETRYABLE_STATUS = new Set([429, 502, 503, 504]);
30
+ /**
31
+ * Decide whether a failed Loki push is worth retrying.
32
+ *
33
+ * Retryable: any error without an HTTP response ( network / timeout / DNS, eg.
34
+ * ECONNREFUSED / ETIMEDOUT / ECONNRESET / EAI_AGAIN ), or an HTTP response with
35
+ * status 429 / 502 / 503 / 504. Everything else ( 4xx client errors like 400 /
36
+ * 401 / 403 / 404, and any other status ) is treated as a permanent error that
37
+ * must surface rather than loop forever.
38
+ */
39
+ function isRetryableLokiError(error) {
40
+ const status = error?.response?.status;
41
+ // No HTTP response -> network / timeout / DNS failure ( axios reports these
42
+ // without a `.response`, carrying codes like ECONNREFUSED / ETIMEDOUT /
43
+ // ECONNRESET / EAI_AGAIN ) -> retryable.
44
+ if (status === undefined) {
45
+ return true;
46
+ }
47
+ return RETRYABLE_STATUS.has(status);
48
+ }
49
+ /**
50
+ * Read a `Retry-After` header from a Loki error response and return the delay in
51
+ * milliseconds. Supports both the numeric ( delta-seconds ) and HTTP-date forms.
52
+ * Returns `undefined` when there is no usable header.
53
+ */
54
+ function retryAfterMs(error) {
55
+ const err = error;
56
+ const headers = err?.response?.headers;
57
+ const raw = headers?.["retry-after"];
58
+ if (raw === undefined || raw === null) {
59
+ return undefined;
60
+ }
61
+ const value = Array.isArray(raw) ? raw[0] : raw;
62
+ // numeric delta-seconds ( either a real number or a numeric string )
63
+ const asNumber = typeof value === "number" ? value : Number(value);
64
+ if (typeof value !== "boolean" && !Number.isNaN(asNumber) && `${value}`.trim() !== "") {
65
+ return Math.max(0, asNumber * 1000);
66
+ }
67
+ // HTTP-date form
68
+ const asDate = Date.parse(String(value));
69
+ if (!Number.isNaN(asDate)) {
70
+ return Math.max(0, asDate - Date.now());
71
+ }
72
+ return undefined;
73
+ }
28
74
  // we mark per instance check becouse we can have multiple file targes
29
75
  // for different files/paths/logs but we dont want to create every time writer for same.
30
76
  let GraphanaLokiLogTarget = class GraphanaLokiLogTarget extends log_1.LogTarget {
31
77
  constructor(options) {
32
78
  super(options);
33
- this.Entries = [];
34
- this.WriteEntries = [];
35
- this.Status = TargetStatus.IDLE;
79
+ /**
80
+ * Set true when the queue overflows maxBufferSize, so the drop warning is
81
+ * emitted ONCE per overflow episode and reset when a flush succeeds.
82
+ */
83
+ this.Overflowed = false;
84
+ // Config-driven targets ( resolved through the logger config ) nest their
85
+ // settings under an `options` sub-object ( like FileTarget ), while direct
86
+ // construction passes them flat. Hoist any nested options onto this.Options
87
+ // at highest precedence so both forms resolve the same flat reads below.
88
+ const nested = (options?.options ?? {});
36
89
  this.Options = Object.assign({
37
90
  interval: 3000,
38
91
  bufferSize: 10,
92
+ maxBufferSize: 1000,
39
93
  timeout: 1000,
40
- }, this.Options);
94
+ }, this.Options, nested);
41
95
  }
42
96
  __checkInstance__(creationOptions) {
43
97
  return this.Options.name === creationOptions[0].name;
44
98
  }
45
99
  resolve() {
100
+ const headers = {
101
+ "Content-Type": "application/json",
102
+ };
103
+ // A Loki endpoint may be unauthenticated: only attach the Basic auth header
104
+ // when credentials are actually configured, so a config without `auth`
105
+ // doesn't throw on `auth.username`.
106
+ if (this.Options.auth?.username) {
107
+ headers.Authorization = `Basic ${Buffer.from(`${this.Options.auth.username}:${this.Options.auth.password}`).toString("base64")}`;
108
+ }
46
109
  this.AxiosInstance = axios_1.default.create({
47
110
  baseURL: this.Options.host,
48
- headers: {
49
- "Content-Type": "application/json",
50
- Authorization: `Basic ${Buffer.from(`${this.Options.auth.username}:${this.Options.auth.password}`).toString("base64")}`,
51
- },
111
+ headers,
52
112
  timeout: this.Options.timeout,
53
113
  });
54
- this.FlushTimer = setInterval(() => {
55
- // do not flush, if we already writting to file
56
- if (this.Status !== TargetStatus.IDLE) {
57
- return;
58
- }
59
- this.WriteEntries = [...this.WriteEntries, ...this.Entries];
60
- this.Entries = [];
61
- setImmediate(() => {
62
- this.flush();
63
- });
64
- }, this.Options.interval ?? 3000);
114
+ // one reusable pipeline: exponential backoff + jitter, 5 attempts, 1s..5s,
115
+ // honoring Retry-After and retrying only transient errors ( network + 429 /
116
+ // 502 / 503 / 504 ). Non-retryable errors fall straight through to .catch.
117
+ this.RetryPipeline = new util_1.ResiliencePipelineBuilder()
118
+ .addRetry({
119
+ MaxRetryAttempts: 5,
120
+ Delay: util_1.TimeSpan.fromSeconds(1),
121
+ MaxDelay: util_1.TimeSpan.fromSeconds(5),
122
+ BackoffType: util_1.BackoffType.Exponential,
123
+ UseJitter: true,
124
+ ShouldHandle: (o) => o.Error !== undefined && isRetryableLokiError(o.Error),
125
+ DelayGenerator: ({ Outcome }) => {
126
+ const ms = retryAfterMs(Outcome.Error);
127
+ return ms !== undefined ? util_1.TimeSpan.fromMilliseconds(ms) : undefined;
128
+ },
129
+ })
130
+ .build();
131
+ // one BatchQueue owns accumulation, the periodic flush timer and the
132
+ // maxQueue cap ( dropping the oldest ). The actual push happens in send().
133
+ this.Queue = new log_1.BatchQueue({
134
+ maxBatch: this.Options.bufferSize,
135
+ maxQueue: this.Options.maxBufferSize,
136
+ flushIntervalMs: this.Options.interval ?? 3000,
137
+ onFlush: (batch) => this.send(batch),
138
+ onOverflow: (droppedItems) => {
139
+ // emit the drop warning ONCE per overflow episode; reset on the next
140
+ // successful send() so a later episode warns again.
141
+ if (!this.Overflowed) {
142
+ this.Overflowed = true;
143
+ this.Log.warn(`Graphana loki buffer exceeded ${this.Options.maxBufferSize} entries, dropped ${droppedItems.length} oldest entries.`);
144
+ }
145
+ // spill each dropped entry to the fallback ( if a wrapper wired one ) so
146
+ // a durable target catches exactly what overflow discarded.
147
+ for (const entry of droppedItems) {
148
+ this.OnDropped?.(entry);
149
+ }
150
+ },
151
+ });
152
+ super.resolve();
65
153
  }
66
154
  write(data) {
67
155
  if (!this.Options.enabled) {
68
156
  return;
69
157
  }
70
158
  data.Variables["n_timestamp"] = new Date().getTime() * 1000000;
71
- this.Entries.push(data);
72
- // if we already writting, skip buffer check & write to file
73
- // wait until write is finished
74
- if (this.Status !== TargetStatus.IDLE) {
75
- return;
76
- }
77
- if (this.Entries.length >= this.Options.bufferSize) {
78
- this.Status = TargetStatus.PENDING;
79
- this.WriteEntries = [...this.WriteEntries, ...this.Entries];
80
- this.Entries = [];
81
- // write at end of nodejs event loop all buffered messages at once
82
- setImmediate(() => {
83
- this.flush();
84
- });
85
- }
159
+ // fire-and-forget: Loki did not await the buffer write before either. A
160
+ // size-triggered flush ( when the batch fills ) runs in the background.
161
+ void this.Queue.enqueue(data);
162
+ }
163
+ forceFlush() {
164
+ return this.Queue ? this.Queue.forceFlush() : Promise.resolve();
86
165
  }
87
166
  async dispose() {
88
- // stop flush timer
89
- clearInterval(this.FlushTimer);
90
- this.WriteEntries = [...this.WriteEntries, ...this.Entries];
91
- this.Entries = [];
92
- // write all messages from buffer
93
- this.flush();
167
+ // stop the flush timer and perform a final best-effort flush.
168
+ await this.Queue.shutdown();
94
169
  }
95
- flush() {
96
- if (this.WriteEntries.length === 0) {
97
- this.Status = TargetStatus.IDLE;
98
- return;
99
- }
170
+ /**
171
+ * Push a single batch to Loki. Wired as the queue's `onFlush`.
172
+ *
173
+ * MUST resolve ( never reject ) so shutdown()/forceFlush() cannot reject: on a
174
+ * retryable-exhausted failure the batch is requeued at the front, on a
175
+ * non-retryable error it is dropped and surfaced via HasError/Error.
176
+ */
177
+ async send(batch) {
100
178
  const streams = new Map();
101
179
  const keyFor = (x) => {
102
180
  return [this.Options.labels.app, x.Variables.logger, x.Variables.level, ...Object.values(this.Options.labels)].join("-");
103
181
  };
104
182
  const valFor = (x) => [x.Variables["n_timestamp"].toString(), (0, configuration_common_1.format)(x.Variables, this.Options.layout)];
105
- this.Status = TargetStatus.WRITTING;
106
- this.WriteEntries.forEach((x) => {
183
+ batch.forEach((x) => {
107
184
  const key = keyFor(x);
108
185
  const stream = streams.get(key);
109
186
  if (!stream) {
@@ -119,17 +196,40 @@ let GraphanaLokiLogTarget = class GraphanaLokiLogTarget extends log_1.LogTarget
119
196
  }
120
197
  stream.values.push(valFor(x));
121
198
  });
122
- this.AxiosInstance.post("/loki/api/v1/push", { streams: [...streams.values()] })
123
- .then(() => {
124
- this.Status = TargetStatus.IDLE;
125
- this.Log.trace(`Wrote buffered messages to graphana target at url ${this.Options.host}, ${this.WriteEntries.length} messages.`);
126
- this.WriteEntries = [];
127
- })
128
- .catch((err) => {
129
- // log error message to others if applicable eg. console
130
- this.Log.error(err, `Cannot write log messages to graphana target`);
131
- this.Status = TargetStatus.IDLE;
132
- });
199
+ // wrap ONLY the push in the resilience pipeline: transient failures are
200
+ // retried inline with backoff; we reach the catch only after retries are
201
+ // exhausted or immediately on a non-retryable error.
202
+ try {
203
+ await this.RetryPipeline.execute(() => this.AxiosInstance.post("/loki/api/v1/push", { streams: [...streams.values()] }).then(() => undefined));
204
+ // successful write -> clear any previous error state
205
+ this.HasError = false;
206
+ this.Error = null;
207
+ // drained successfully - allow the next overflow episode to warn again
208
+ this.Overflowed = false;
209
+ this.Log.trace(`Wrote buffered messages to graphana target at url ${this.Options.host}, ${batch.length} messages.`);
210
+ }
211
+ catch (err) {
212
+ // reached only after retries are exhausted ( transient ) or immediately
213
+ // for a non-retryable error.
214
+ this.HasError = true;
215
+ this.Error = err;
216
+ if (isRetryableLokiError(err)) {
217
+ // retryable but exhausted: put the batch back at the front so the next
218
+ // flush retries it. The queue enforces the maxQueue cap ( dropping the
219
+ // oldest + onOverflow ) so the retry buffer never grows without bound.
220
+ this.Log.error(err, `Cannot write log messages to graphana target - retries exhausted, retaining entries for next flush.`);
221
+ this.Queue.requeueFront(batch);
222
+ return;
223
+ }
224
+ // permanent error ( eg. 400 malformed, 401 bad auth ): retrying forever
225
+ // would only hide a config problem. Drop the batch and surface it, but
226
+ // first spill each undelivered entry to the fallback ( if a wrapper wired
227
+ // one ) so a durable target catches exactly what was not delivered.
228
+ for (const entry of batch) {
229
+ this.OnDropped?.(entry);
230
+ }
231
+ this.Log.error(err, `Cannot write log messages to graphana target - dropping ${batch.length} entries because the error is non-retryable.`);
232
+ }
133
233
  }
134
234
  };
135
235
  exports.GraphanaLokiLogTarget = GraphanaLokiLogTarget;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,31 @@
1
1
  import { IInstanceCheck } from "@spinajs/di";
2
- import { Log, ILogEntry, LogTarget, ICommonTargetOptions } from "@spinajs/log";
3
- import { Axios } from "axios";
2
+ import { Log, ILogEntry, LogTarget, ICommonTargetOptions, BatchQueue } from "@spinajs/log";
3
+ import { AxiosInstance } from "axios";
4
+ import { ResiliencePipeline } from "@spinajs/util";
5
+ /**
6
+ * Decide whether a failed Loki push is worth retrying.
7
+ *
8
+ * Retryable: any error without an HTTP response ( network / timeout / DNS, eg.
9
+ * ECONNREFUSED / ETIMEDOUT / ECONNRESET / EAI_AGAIN ), or an HTTP response with
10
+ * status 429 / 502 / 503 / 504. Everything else ( 4xx client errors like 400 /
11
+ * 401 / 403 / 404, and any other status ) is treated as a permanent error that
12
+ * must surface rather than loop forever.
13
+ */
14
+ export declare function isRetryableLokiError(error: unknown): boolean;
15
+ /**
16
+ * Read a `Retry-After` header from a Loki error response and return the delay in
17
+ * milliseconds. Supports both the numeric ( delta-seconds ) and HTTP-date forms.
18
+ * Returns `undefined` when there is no usable header.
19
+ */
20
+ export declare function retryAfterMs(error: unknown): number | undefined;
4
21
  export interface IGraphanaOptions extends ICommonTargetOptions {
5
22
  interval: number;
6
23
  bufferSize: number;
24
+ /**
25
+ * Hard cap on the number of entries retained for retry. When a flush fails and the
26
+ * retained + newly buffered entries exceed this, the oldest are dropped.
27
+ */
28
+ maxBufferSize: number;
7
29
  timeout: number;
8
30
  host: string;
9
31
  auth: {
@@ -14,24 +36,38 @@ export interface IGraphanaOptions extends ICommonTargetOptions {
14
36
  app: string;
15
37
  };
16
38
  }
17
- declare enum TargetStatus {
18
- WRITTING = 0,
19
- PENDING = 1,
20
- IDLE = 2
21
- }
22
39
  export declare class GraphanaLokiLogTarget extends LogTarget<IGraphanaOptions> implements IInstanceCheck {
23
40
  protected Log: Log;
24
- protected Entries: ILogEntry[];
25
- protected WriteEntries: ILogEntry[];
26
- protected Status: TargetStatus;
27
- protected FlushTimer: NodeJS.Timeout;
28
- protected AxiosInstance: Axios;
41
+ /**
42
+ * The single buffered-batch queue that owns accumulation, the flush timer and
43
+ * the maxQueue cap. The actual Loki push happens in `send`, wired as its
44
+ * `onFlush`.
45
+ */
46
+ protected Queue: BatchQueue<ILogEntry>;
47
+ /**
48
+ * Set true when the queue overflows maxBufferSize, so the drop warning is
49
+ * emitted ONCE per overflow episode and reset when a flush succeeds.
50
+ */
51
+ protected Overflowed: boolean;
52
+ protected AxiosInstance: AxiosInstance;
53
+ /**
54
+ * Reusable resilience pipeline guarding the Loki push with exponential
55
+ * backoff + jitter, honoring `Retry-After` and only retrying transient errors.
56
+ */
57
+ protected RetryPipeline: ResiliencePipeline<void>;
29
58
  constructor(options: IGraphanaOptions);
30
59
  __checkInstance__(creationOptions: IGraphanaOptions[]): boolean;
31
60
  resolve(): void;
32
61
  write(data: ILogEntry): void;
62
+ forceFlush(): Promise<void>;
33
63
  dispose(): Promise<void>;
34
- protected flush(): void;
64
+ /**
65
+ * Push a single batch to Loki. Wired as the queue's `onFlush`.
66
+ *
67
+ * MUST resolve ( never reject ) so shutdown()/forceFlush() cannot reject: on a
68
+ * retryable-exhausted failure the batch is requeued at the front, on a
69
+ * non-retryable error it is dropped and surfaced via HasError/Error.
70
+ */
71
+ protected send(batch: ILogEntry[]): Promise<void>;
35
72
  }
36
- export {};
37
73
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAgC,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,oBAAoB,EAAU,MAAM,cAAc,CAAC;AAGvF,OAAc,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAGrC,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAE5D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAWD,aAAK,YAAY;IACf,QAAQ,IAAA;IACR,OAAO,IAAA;IACP,IAAI,IAAA;CACL;AAID,qBAEa,qBAAsB,SAAQ,SAAS,CAAC,gBAAgB,CAAE,YAAW,cAAc;IAE9F,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,CAAM;IACpC,SAAS,CAAC,YAAY,EAAE,SAAS,EAAE,CAAM;IAEzC,SAAS,CAAC,MAAM,EAAE,YAAY,CAAqB;IAEnD,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC;IACrC,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC;gBAEnB,OAAO,EAAE,gBAAgB;IAarC,iBAAiB,CAAC,eAAe,EAAE,gBAAgB,EAAE,GAAG,OAAO;IAIxD,OAAO,IAAI,IAAI;IAyBf,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IA2BtB,OAAO;IAWpB,SAAS,CAAC,KAAK;CA8ChB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAgC,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,oBAAoB,EAAU,UAAU,EAAE,MAAM,cAAc,CAAC;AAGnG,OAAc,EAAc,aAAa,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAe,kBAAkB,EAAuC,MAAM,eAAe,CAAC;AAQrG;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAW5D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAwB/D;AAED,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAE5D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAaD,qBAEa,qBAAsB,SAAQ,SAAS,CAAC,gBAAgB,CAAE,YAAW,cAAc;IAE9F,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAEvC;;;OAGG;IACH,SAAS,CAAC,UAAU,UAAS;IAE7B,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IAEvC;;;OAGG;IACH,SAAS,CAAC,aAAa,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAEtC,OAAO,EAAE,gBAAgB;IAoBrC,iBAAiB,CAAC,eAAe,EAAE,gBAAgB,EAAE,GAAG,OAAO;IAIxD,OAAO,IAAI,IAAI;IA8Df,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAY5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,OAAO;IAKpB;;;;;;OAMG;cACa,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAkExD"}