Skip to content

Commit

Permalink
refactor!: reduce types complexity & enhance some properties name
Browse files Browse the repository at this point in the history
  • Loading branch information
fraxken committed Jul 2, 2024
1 parent 5a3ee80 commit f9967c1
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 100 deletions.
31 changes: 16 additions & 15 deletions docs/Loki.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ interface LokiQueryStreamOptions<T extends LokiPatternType> extends LokiQueryOpt

The response is described by the following interface:
```ts
export interface QueryRangeResponse<T extends LokiPatternType> {
values: LokiLiteralPattern<T>[];
interface QueryRangeLogsResponse<T extends LokiPatternType> {
logs: LokiLiteralPattern<T>[];
timerange: TimeRange | null;
}
```
Expand Down Expand Up @@ -92,14 +92,14 @@ for (const { stream, values } of logs) {

The response is described by the following interface:
```ts
interface QueryRangeStreamResponse<T extends LokiPatternType> {
logs: LokiStreamResult<LokiLiteralPattern<T>>[];
timerange: TimeRange | null;
interface LokiCombined<T = string> {
labels: LokiLabels;
values: [unixEpoch: number, log: T][];
}

interface LokiStreamResult<T> {
stream: Record<string, string>;
values: [unixEpoch: number, value: T][];
interface QueryRangeStreamResponse<T extends LokiPatternType> {
streams: LokiCombined<LokiLiteralPattern<T>>[];
timerange: TimeRange | null;
}
```

Expand All @@ -118,14 +118,14 @@ count_over_time({ label="value" }[5m])
The response is described by the following interface:

```ts
interface QueryRangeMatrixResponse {
logs: LokiMatrix[];
timerange: TimeRange | null;
interface LokiCombined<T = string> {
labels: LokiLabels;
values: [unixEpoch: number, log: T][];
}

interface LokiMatrix {
metric: Record<string, string>;
values: [unixEpoch: number, value: string][];
interface QueryRangeMatrixResponse {
metrics: LokiCombined<string>[];
timerange: TimeRange | null;
}
```

Expand Down Expand Up @@ -223,7 +223,8 @@ async series<T = Record<string, string>>(
```

## Pattern usage
**queryRange** and **queryRangeStream** API allow the usage of pattern.

**queryRange** and **queryRangeStream** APIs allow the usage of pattern.

```ts
import { GrafanaApi } from "@myunisoft/loki";
Expand Down
29 changes: 16 additions & 13 deletions src/class/Loki.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ import * as utils from "../utils.js";
import {
LokiStandardBaseResponse,
RawQueryRangeResponse,
LokiStream,
LokiMatrix,
QueryRangeResponse,
QueryRangeLogsResponse,
QueryRangeStreamResponse,
QueryRangeMatrixResponse
} from "../types.js";
Expand Down Expand Up @@ -92,7 +90,7 @@ export class Loki {
this.credential = credential;
}

#fetchQueryRange<T>(
#fetchQueryRange<T extends "matrix" | "streams">(
logQL: LogQL | string,
options: LokiQueryOptions = {}
): Promise<httpie.RequestResponse<RawQueryRangeResponse<T>>> {
Expand Down Expand Up @@ -121,13 +119,18 @@ export class Loki {
throw new Error("Log queries must use `queryRangeStream` method");
}

const { data } = await this.#fetchQueryRange<LokiMatrix>(
const { data } = await this.#fetchQueryRange<"matrix">(
logQL,
options
);

return {
logs: data.data.result,
metrics: data.data.result.map((result) => {
return {
labels: result.metric,
values: result.values
};
}),
timerange: utils.streamOrMatrixTimeRange(data.data.result)
};
}
Expand All @@ -144,15 +147,15 @@ export class Loki {
const parser: PatternShape<any> = pattern instanceof NoopPattern ?
pattern : new Pattern(pattern);

const { data } = await this.#fetchQueryRange<LokiStream>(
const { data } = await this.#fetchQueryRange<"streams">(
logQL,
options
);

return {
logs: data.data.result.map((result) => {
streams: data.data.result.map((result) => {
return {
stream: result.stream,
labels: result.stream,
values: result.values
.map(([unixEpoch, log]) => [unixEpoch, ...parser.executeOnLogs([log])])
.filter((log) => log.length > 1) as any[]
Expand All @@ -165,22 +168,22 @@ export class Loki {
async queryRange<T extends LokiPatternType = string>(
logQL: LogQL | string,
options: LokiQueryStreamOptions<T> = {}
): Promise<QueryRangeResponse<T>> {
): Promise<QueryRangeLogsResponse<T>> {
const { pattern = new NoopPattern() } = options;
const parser: PatternShape<any> = pattern instanceof NoopPattern ?
pattern : new Pattern(pattern);

const { data } = await this.#fetchQueryRange<LokiMatrix | LokiStream>(logQL, options);
const { data } = await this.#fetchQueryRange<"streams">(logQL, options);

const inlinedLogs = utils.inlineLogs(data);
if (inlinedLogs === null) {
return {
values: [], timerange: null
logs: [], timerange: null
};
}

return {
values: parser.executeOnLogs(inlinedLogs.values) as any[],
logs: parser.executeOnLogs(inlinedLogs.values) as any[],
timerange: inlinedLogs.timerange
};
}
Expand Down
121 changes: 66 additions & 55 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,80 +7,91 @@ import {
// Import Internal Dependencies
import { TimeRange } from "./utils.js";

export interface LokiStream {
stream: Record<string, string>;
values: [unixEpoch: number, log: string][];
}

export interface LokiMatrix {
metric: Record<string, string>;
values: [unixEpoch: number, value: string][];
export type LokiStandardBaseResponse<S> = {
status: "failed";
} | {
status: "success";
data: S;
}

export interface LokiStreamResult<T> {
stream: Record<string, string>;
values: [unixEpoch: number, value: T][];
export interface LokiQueryRangeStats {
summary: {
bytesProcessedPerSecond: number;
linesProcessedPerSecond: number;
totalBytesProcessed: number;
totalLinesProcessed: number;
execTime: number;
};
store: {
totalChunksRef: number;
totalChunksDownloaded: number;
chunksDownloadTime: number;
headChunkBytes: number;
headChunkLines: number;
decompressedBytes: number;
decompressedLines: number;
compressedBytes: number;
totalDuplicates: number;
};
ingester: {
totalReached: number;
totalChunksMatched: number;
totalBatches: number;
totalLinesSent: number;
headChunkBytes: number;
headChunkLines: number;
decompressedBytes: number;
decompressedLines: number;
compressedBytes: number;
totalDuplicates: number;
}
}

export interface RawQueryRangeResponse<T = LokiStream> {
interface RawQueryRangeTemplate<
Type extends "matrix" | "streams",
Result extends LokiMatrix | LokiStream
> {
status: "success";
data: {
resultType: "matrix" | "streams";
result: T[];
stats: {
summary: {
bytesProcessedPerSecond: number;
linesProcessedPerSecond: number;
totalBytesProcessed: number;
totalLinesProcessed: number;
execTime: number;
};
store: {
totalChunksRef: number;
totalChunksDownloaded: number;
chunksDownloadTime: number;
headChunkBytes: number;
headChunkLines: number;
decompressedBytes: number;
decompressedLines: number;
compressedBytes: number;
totalDuplicates: number;
};
ingester: {
totalReached: number;
totalChunksMatched: number;
totalBatches: number;
totalLinesSent: number;
headChunkBytes: number;
headChunkLines: number;
decompressedBytes: number;
decompressedLines: number;
compressedBytes: number;
totalDuplicates: number;
}
};
resultType: Type;
result: Result[];
stats: LokiQueryRangeStats;
}
}

export type LokiStandardBaseResponse<S> = {
status: "failed";
} | {
status: "success";
data: S;
export type RawQueryRangeResponse<T extends "matrix" | "streams"> = T extends "matrix" ?
RawQueryRangeTemplate<T, LokiMatrix> :
RawQueryRangeTemplate<T, LokiStream>;

export type LokiLabels = Record<string, string>;

export interface LokiStream<T = string> {
stream: LokiLabels;
values: [unixEpoch: number, log: T][];
}

export interface LokiMatrix {
metric: LokiLabels;
values: [unixEpoch: number, metric: string][];
}

export interface LokiCombined<T = string> {
labels: LokiLabels;
values: [unixEpoch: number, log: T][];
}

export interface QueryRangeResponse<T extends LokiPatternType> {
values: LokiLiteralPattern<T>[];
export interface QueryRangeLogsResponse<T extends LokiPatternType> {
logs: LokiLiteralPattern<T>[];
timerange: TimeRange | null;
}

export interface QueryRangeStreamResponse<T extends LokiPatternType> {
logs: LokiStreamResult<LokiLiteralPattern<T>>[];
streams: LokiCombined<LokiLiteralPattern<T>>[];
timerange: TimeRange | null;
}

export interface QueryRangeMatrixResponse {
logs: LokiMatrix[];
metrics: LokiCombined<string>[];
timerange: TimeRange | null;
}

Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function transformStreamOrMatrixValue(
export type TimeRange = [first: number, last: number];

export function inlineLogs(
result: RawQueryRangeResponse<LokiStream | LokiMatrix>
result: RawQueryRangeResponse<"streams">
): null | { values: string[], timerange: TimeRange } {
if (result.status !== "success") {
return null;
Expand Down
24 changes: 12 additions & 12 deletions test/Loki.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ describe("GrafanaApi.Loki", () => {
const sdk = new GrafanaApi({ remoteApiURL: kDummyURL });

const result = await sdk.Loki.queryRangeMatrix("count_over_time({app='foo'} [5m])");
const resultLogs = result.logs[0]!;
const resultLogs = result.metrics[0]!;

assert.ok(
resultLogs.values.every((arr) => typeof arr[0] === "number")
Expand All @@ -91,7 +91,7 @@ describe("GrafanaApi.Loki", () => {
resultLogs.values.map((arr) => arr[1]),
expectedLogs.slice(0)
);
assert.deepEqual(resultLogs.metric, { foo: "bar" });
assert.deepEqual(resultLogs.labels, { foo: "bar" });
});
});

Expand Down Expand Up @@ -132,14 +132,14 @@ describe("GrafanaApi.Loki", () => {
const result = await sdk.Loki.queryRangeStream("{app='foo'}", {
pattern: "hello '<name>'"
});
const resultLogs = result.logs[0]!;
const resultLogs = result.streams[0]!;

assert.strictEqual(result.logs.length, 1);
assert.strictEqual(result.streams.length, 1);
assert.deepEqual(
resultLogs.values[0][1],
{ name: "Thomas" }
);
assert.deepEqual(resultLogs.stream, { foo: "bar" });
assert.deepEqual(resultLogs.labels, { foo: "bar" });
});

it("should return expectedLogs with no modification (using NoopParser)", async() => {
Expand All @@ -156,7 +156,7 @@ describe("GrafanaApi.Loki", () => {
const sdk = new GrafanaApi({ remoteApiURL: kDummyURL });

const result = await sdk.Loki.queryRangeStream("{app='foo'}");
const resultLogs = result.logs[0]!;
const resultLogs = result.streams[0]!;

assert.ok(
resultLogs.values.every((arr) => typeof arr[0] === "number")
Expand All @@ -165,7 +165,7 @@ describe("GrafanaApi.Loki", () => {
resultLogs.values.map((arr) => arr[1]),
expectedLogs.slice(0)
);
assert.deepEqual(resultLogs.stream, { foo: "bar" });
assert.deepEqual(resultLogs.labels, { foo: "bar" });
});

it("should return empty list of logs (using LogParser)", async() => {
Expand All @@ -186,7 +186,7 @@ describe("GrafanaApi.Loki", () => {
});

assert.deepEqual(
result.logs,
result.streams,
expectedLogs
);
});
Expand All @@ -207,7 +207,7 @@ describe("GrafanaApi.Loki", () => {
const result = await sdk.Loki.queryRangeStream("{app='foo'}");

assert.deepEqual(
result.logs,
result.streams,
expectedLogs
);
});
Expand Down Expand Up @@ -237,7 +237,7 @@ describe("GrafanaApi.Loki", () => {

const result = await sdk.Loki.queryRange("{app='foo'}");
assert.deepEqual(
result.values,
result.logs,
expectedLogs.slice(0).reverse()
);
});
Expand All @@ -258,9 +258,9 @@ describe("GrafanaApi.Loki", () => {
const result = await sdk.Loki.queryRange("{app='foo'}", {
pattern: "hello '<name>'"
});
assert.strictEqual(result.values.length, 1);
assert.strictEqual(result.logs.length, 1);
assert.deepEqual(
result.values[0],
result.logs[0],
{ name: "Thomas" }
);
});
Expand Down
Loading

0 comments on commit f9967c1

Please sign in to comment.