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

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/lib/mjs/index.js CHANGED
@@ -11,93 +11,168 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  /* eslint-disable security/detect-object-injection */
12
12
  import { format } from "@spinajs/configuration-common";
13
13
  import { Injectable, PerInstanceCheck } from "@spinajs/di";
14
- import { Log, LogTarget, Logger } from "@spinajs/log";
14
+ import { Log, LogTarget, Logger, BatchQueue } from "@spinajs/log";
15
15
  import axios from "axios";
16
- var TargetStatus;
17
- (function (TargetStatus) {
18
- TargetStatus[TargetStatus["WRITTING"] = 0] = "WRITTING";
19
- TargetStatus[TargetStatus["PENDING"] = 1] = "PENDING";
20
- TargetStatus[TargetStatus["IDLE"] = 2] = "IDLE";
21
- })(TargetStatus || (TargetStatus = {}));
16
+ import { BackoffType, ResiliencePipelineBuilder, TimeSpan } from "@spinajs/util";
17
+ /**
18
+ * HTTP status codes worth retrying against Loki: rate limiting and transient
19
+ * upstream / gateway failures.
20
+ */
21
+ const RETRYABLE_STATUS = new Set([429, 502, 503, 504]);
22
+ /**
23
+ * Decide whether a failed Loki push is worth retrying.
24
+ *
25
+ * Retryable: any error without an HTTP response ( network / timeout / DNS, eg.
26
+ * ECONNREFUSED / ETIMEDOUT / ECONNRESET / EAI_AGAIN ), or an HTTP response with
27
+ * status 429 / 502 / 503 / 504. Everything else ( 4xx client errors like 400 /
28
+ * 401 / 403 / 404, and any other status ) is treated as a permanent error that
29
+ * must surface rather than loop forever.
30
+ */
31
+ export function isRetryableLokiError(error) {
32
+ const status = error?.response?.status;
33
+ // No HTTP response -> network / timeout / DNS failure ( axios reports these
34
+ // without a `.response`, carrying codes like ECONNREFUSED / ETIMEDOUT /
35
+ // ECONNRESET / EAI_AGAIN ) -> retryable.
36
+ if (status === undefined) {
37
+ return true;
38
+ }
39
+ return RETRYABLE_STATUS.has(status);
40
+ }
41
+ /**
42
+ * Read a `Retry-After` header from a Loki error response and return the delay in
43
+ * milliseconds. Supports both the numeric ( delta-seconds ) and HTTP-date forms.
44
+ * Returns `undefined` when there is no usable header.
45
+ */
46
+ export function retryAfterMs(error) {
47
+ const err = error;
48
+ const headers = err?.response?.headers;
49
+ const raw = headers?.["retry-after"];
50
+ if (raw === undefined || raw === null) {
51
+ return undefined;
52
+ }
53
+ const value = Array.isArray(raw) ? raw[0] : raw;
54
+ // numeric delta-seconds ( either a real number or a numeric string )
55
+ const asNumber = typeof value === "number" ? value : Number(value);
56
+ if (typeof value !== "boolean" && !Number.isNaN(asNumber) && `${value}`.trim() !== "") {
57
+ return Math.max(0, asNumber * 1000);
58
+ }
59
+ // HTTP-date form
60
+ const asDate = Date.parse(String(value));
61
+ if (!Number.isNaN(asDate)) {
62
+ return Math.max(0, asDate - Date.now());
63
+ }
64
+ return undefined;
65
+ }
22
66
  // we mark per instance check becouse we can have multiple file targes
23
67
  // for different files/paths/logs but we dont want to create every time writer for same.
24
68
  let GraphanaLokiLogTarget = class GraphanaLokiLogTarget extends LogTarget {
25
69
  constructor(options) {
26
70
  super(options);
27
- this.Entries = [];
28
- this.WriteEntries = [];
29
- this.Status = TargetStatus.IDLE;
71
+ /**
72
+ * Set true when the queue overflows maxBufferSize, so the drop warning is
73
+ * emitted ONCE per overflow episode and reset when a flush succeeds.
74
+ */
75
+ this.Overflowed = false;
76
+ // Config-driven targets ( resolved through the logger config ) nest their
77
+ // settings under an `options` sub-object ( like FileTarget ), while direct
78
+ // construction passes them flat. Hoist any nested options onto this.Options
79
+ // at highest precedence so both forms resolve the same flat reads below.
80
+ const nested = (options?.options ?? {});
30
81
  this.Options = Object.assign({
31
82
  interval: 3000,
32
83
  bufferSize: 10,
84
+ maxBufferSize: 1000,
33
85
  timeout: 1000,
34
- }, this.Options);
86
+ }, this.Options, nested);
35
87
  }
36
88
  __checkInstance__(creationOptions) {
37
89
  return this.Options.name === creationOptions[0].name;
38
90
  }
39
91
  resolve() {
92
+ const headers = {
93
+ "Content-Type": "application/json",
94
+ };
95
+ // A Loki endpoint may be unauthenticated: only attach the Basic auth header
96
+ // when credentials are actually configured, so a config without `auth`
97
+ // doesn't throw on `auth.username`.
98
+ if (this.Options.auth?.username) {
99
+ headers.Authorization = `Basic ${Buffer.from(`${this.Options.auth.username}:${this.Options.auth.password}`).toString("base64")}`;
100
+ }
40
101
  this.AxiosInstance = axios.create({
41
102
  baseURL: this.Options.host,
42
- headers: {
43
- "Content-Type": "application/json",
44
- Authorization: `Basic ${Buffer.from(`${this.Options.auth.username}:${this.Options.auth.password}`).toString("base64")}`,
45
- },
103
+ headers,
46
104
  timeout: this.Options.timeout,
47
105
  });
48
- this.FlushTimer = setInterval(() => {
49
- // do not flush, if we already writting to file
50
- if (this.Status !== TargetStatus.IDLE) {
51
- return;
52
- }
53
- this.WriteEntries = [...this.WriteEntries, ...this.Entries];
54
- this.Entries = [];
55
- setImmediate(() => {
56
- this.flush();
57
- });
58
- }, this.Options.interval ?? 3000);
106
+ // one reusable pipeline: exponential backoff + jitter, 5 attempts, 1s..5s,
107
+ // honoring Retry-After and retrying only transient errors ( network + 429 /
108
+ // 502 / 503 / 504 ). Non-retryable errors fall straight through to .catch.
109
+ this.RetryPipeline = new ResiliencePipelineBuilder()
110
+ .addRetry({
111
+ MaxRetryAttempts: 5,
112
+ Delay: TimeSpan.fromSeconds(1),
113
+ MaxDelay: TimeSpan.fromSeconds(5),
114
+ BackoffType: BackoffType.Exponential,
115
+ UseJitter: true,
116
+ ShouldHandle: (o) => o.Error !== undefined && isRetryableLokiError(o.Error),
117
+ DelayGenerator: ({ Outcome }) => {
118
+ const ms = retryAfterMs(Outcome.Error);
119
+ return ms !== undefined ? TimeSpan.fromMilliseconds(ms) : undefined;
120
+ },
121
+ })
122
+ .build();
123
+ // one BatchQueue owns accumulation, the periodic flush timer and the
124
+ // maxQueue cap ( dropping the oldest ). The actual push happens in send().
125
+ this.Queue = new BatchQueue({
126
+ maxBatch: this.Options.bufferSize,
127
+ maxQueue: this.Options.maxBufferSize,
128
+ flushIntervalMs: this.Options.interval ?? 3000,
129
+ onFlush: (batch) => this.send(batch),
130
+ onOverflow: (droppedItems) => {
131
+ // emit the drop warning ONCE per overflow episode; reset on the next
132
+ // successful send() so a later episode warns again.
133
+ if (!this.Overflowed) {
134
+ this.Overflowed = true;
135
+ this.Log.warn(`Graphana loki buffer exceeded ${this.Options.maxBufferSize} entries, dropped ${droppedItems.length} oldest entries.`);
136
+ }
137
+ // spill each dropped entry to the fallback ( if a wrapper wired one ) so
138
+ // a durable target catches exactly what overflow discarded.
139
+ for (const entry of droppedItems) {
140
+ this.OnDropped?.(entry);
141
+ }
142
+ },
143
+ });
144
+ super.resolve();
59
145
  }
60
146
  write(data) {
61
147
  if (!this.Options.enabled) {
62
148
  return;
63
149
  }
64
150
  data.Variables["n_timestamp"] = new Date().getTime() * 1000000;
65
- this.Entries.push(data);
66
- // if we already writting, skip buffer check & write to file
67
- // wait until write is finished
68
- if (this.Status !== TargetStatus.IDLE) {
69
- return;
70
- }
71
- if (this.Entries.length >= this.Options.bufferSize) {
72
- this.Status = TargetStatus.PENDING;
73
- this.WriteEntries = [...this.WriteEntries, ...this.Entries];
74
- this.Entries = [];
75
- // write at end of nodejs event loop all buffered messages at once
76
- setImmediate(() => {
77
- this.flush();
78
- });
79
- }
151
+ // fire-and-forget: Loki did not await the buffer write before either. A
152
+ // size-triggered flush ( when the batch fills ) runs in the background.
153
+ void this.Queue.enqueue(data);
154
+ }
155
+ forceFlush() {
156
+ return this.Queue ? this.Queue.forceFlush() : Promise.resolve();
80
157
  }
81
158
  async dispose() {
82
- // stop flush timer
83
- clearInterval(this.FlushTimer);
84
- this.WriteEntries = [...this.WriteEntries, ...this.Entries];
85
- this.Entries = [];
86
- // write all messages from buffer
87
- this.flush();
159
+ // stop the flush timer and perform a final best-effort flush.
160
+ await this.Queue.shutdown();
88
161
  }
89
- flush() {
90
- if (this.WriteEntries.length === 0) {
91
- this.Status = TargetStatus.IDLE;
92
- return;
93
- }
162
+ /**
163
+ * Push a single batch to Loki. Wired as the queue's `onFlush`.
164
+ *
165
+ * MUST resolve ( never reject ) so shutdown()/forceFlush() cannot reject: on a
166
+ * retryable-exhausted failure the batch is requeued at the front, on a
167
+ * non-retryable error it is dropped and surfaced via HasError/Error.
168
+ */
169
+ async send(batch) {
94
170
  const streams = new Map();
95
171
  const keyFor = (x) => {
96
172
  return [this.Options.labels.app, x.Variables.logger, x.Variables.level, ...Object.values(this.Options.labels)].join("-");
97
173
  };
98
174
  const valFor = (x) => [x.Variables["n_timestamp"].toString(), format(x.Variables, this.Options.layout)];
99
- this.Status = TargetStatus.WRITTING;
100
- this.WriteEntries.forEach((x) => {
175
+ batch.forEach((x) => {
101
176
  const key = keyFor(x);
102
177
  const stream = streams.get(key);
103
178
  if (!stream) {
@@ -113,17 +188,40 @@ let GraphanaLokiLogTarget = class GraphanaLokiLogTarget extends LogTarget {
113
188
  }
114
189
  stream.values.push(valFor(x));
115
190
  });
116
- this.AxiosInstance.post("/loki/api/v1/push", { streams: [...streams.values()] })
117
- .then(() => {
118
- this.Status = TargetStatus.IDLE;
119
- this.Log.trace(`Wrote buffered messages to graphana target at url ${this.Options.host}, ${this.WriteEntries.length} messages.`);
120
- this.WriteEntries = [];
121
- })
122
- .catch((err) => {
123
- // log error message to others if applicable eg. console
124
- this.Log.error(err, `Cannot write log messages to graphana target`);
125
- this.Status = TargetStatus.IDLE;
126
- });
191
+ // wrap ONLY the push in the resilience pipeline: transient failures are
192
+ // retried inline with backoff; we reach the catch only after retries are
193
+ // exhausted or immediately on a non-retryable error.
194
+ try {
195
+ await this.RetryPipeline.execute(() => this.AxiosInstance.post("/loki/api/v1/push", { streams: [...streams.values()] }).then(() => undefined));
196
+ // successful write -> clear any previous error state
197
+ this.HasError = false;
198
+ this.Error = null;
199
+ // drained successfully - allow the next overflow episode to warn again
200
+ this.Overflowed = false;
201
+ this.Log.trace(`Wrote buffered messages to graphana target at url ${this.Options.host}, ${batch.length} messages.`);
202
+ }
203
+ catch (err) {
204
+ // reached only after retries are exhausted ( transient ) or immediately
205
+ // for a non-retryable error.
206
+ this.HasError = true;
207
+ this.Error = err;
208
+ if (isRetryableLokiError(err)) {
209
+ // retryable but exhausted: put the batch back at the front so the next
210
+ // flush retries it. The queue enforces the maxQueue cap ( dropping the
211
+ // oldest + onOverflow ) so the retry buffer never grows without bound.
212
+ this.Log.error(err, `Cannot write log messages to graphana target - retries exhausted, retaining entries for next flush.`);
213
+ this.Queue.requeueFront(batch);
214
+ return;
215
+ }
216
+ // permanent error ( eg. 400 malformed, 401 bad auth ): retrying forever
217
+ // would only hide a config problem. Drop the batch and surface it, but
218
+ // first spill each undelivered entry to the fallback ( if a wrapper wired
219
+ // one ) so a durable target catches exactly what was not delivered.
220
+ for (const entry of batch) {
221
+ this.OnDropped?.(entry);
222
+ }
223
+ this.Log.error(err, `Cannot write log messages to graphana target - dropping ${batch.length} entries because the error is non-retryable.`);
224
+ }
127
225
  }
128
226
  };
129
227
  __decorate([
@@ -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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"}