Skip to content

Commit

Permalink
feat: implement @sigyn/pattern to replace LogParser (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
fraxken authored Nov 23, 2023
1 parent 71f20e0 commit 896d910
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 380 deletions.
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ const logs = await api.Loki.queryRange(
console.log(logs);
```

You can also provide a Loki pattern to automatically parse logs (and infer the right type with TypeScript)

```ts
const logs = await api.Loki.queryRange(
`{app="serviceName", env="production"}`
{
pattern: "<verb> <_> <endpoint>"
}
);
for (const { verb, endpoint } of logs) {
console.log({verb, endpoint });
}
```

## API

### GrafanaAPI
Expand All @@ -85,8 +99,6 @@ export interface GrafanaApiOptions {
- [Loki](./docs/Loki.md)
- [Datasources](./docs/Datasources.md)

You can also parse logs using our internal [LogParser](./docs/LogParser.md) implementation.

## Contributors ✨

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
Expand Down
67 changes: 0 additions & 67 deletions docs/LogParser.md

This file was deleted.

33 changes: 28 additions & 5 deletions docs/Loki.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ export interface LokiQueryOptions<T> {
start?: number | string;
end?: number | string;
since?: string;
parser?: LogParserLike<T>;
pattern?: T | Array<T> | ReadonlyArray<T>;
}
```

<em>start</em> and <em>end</em> arguments can be either a unix timestamp or a duration like `6h`.

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

The response is described by the following interface:
```ts
interface QueryRangeStreamResponse<T> {
logs: LokiStreamResult<T>[];
export interface QueryRangeStreamResponse<T extends LokiPatternType> {
logs: LokiStreamResult<LokiLiteralPattern<T>>[];
timerange: TimeRange | null;
}

Expand Down Expand Up @@ -178,3 +178,26 @@ async series<T = Record<string, string>>(
...match: [StreamSelector | string, ...(StreamSelector | string)[]]
): Promise<T[]>
```

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

```ts
import { GrafanaApi } from "@myunisoft/loki";

const api = new GrafanaApi({
remoteApiURL: "https://name.loki.com"
});

await api.Loki.queryRange("...", {
pattern: "<pattern> <here>"
});

// or use an Array (tuple)
await api.Loki.queryRange("...", {
pattern: [
"<pattern> ",
"<here>
] as const
});
```
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@myunisoft/httpie": "^2.0.1",
"@openally/auto-url": "^1.0.1",
"@sigyn/logql": "^2.0.0",
"@sigyn/pattern": "^1.0.0",
"dayjs": "^1.11.10",
"ms": "^2.1.3"
}
Expand Down
111 changes: 0 additions & 111 deletions src/class/LogParser.class.ts

This file was deleted.

32 changes: 22 additions & 10 deletions src/class/Loki.class.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
// Import Third-party Dependencies
import * as httpie from "@myunisoft/httpie";
import autoURL from "@openally/auto-url";
import { LogQL, StreamSelector } from "@sigyn/logql";
import {
LogQL,
StreamSelector
} from "@sigyn/logql";
import {
Pattern,
NoopPattern,
LokiPatternType,
PatternShape
} from "@sigyn/pattern";

// Import Internal Dependencies
import * as utils from "../utils.js";
Expand All @@ -14,7 +23,6 @@ import {
QueryRangeStreamResponse
} from "../types.js";
import { ApiCredential } from "./ApiCredential.class.js";
import { NoopLogParser, LogParserLike } from "./LogParser.class.js";

// CONSTANTS
const kDurationTransformer = (value: string | number) => utils.durationToUnixTimestamp(value);
Expand All @@ -33,8 +41,8 @@ interface LokiQueryBaseOptions {
since?: string;
}

export interface LokiQueryOptions<T> extends LokiQueryBaseOptions {
parser?: LogParserLike<T>;
export interface LokiQueryOptions<T extends LokiPatternType> extends LokiQueryBaseOptions {
pattern?: T;
}

export interface LokiLabelsOptions {
Expand Down Expand Up @@ -104,30 +112,34 @@ export class Loki {
);
}

async queryRangeStream<T = string>(
async queryRangeStream<T extends LokiPatternType = string>(
logQL: LogQL | string,
options: LokiQueryOptions<T> = {}
): Promise<QueryRangeStreamResponse<T>> {
const { parser = new NoopLogParser<T>() } = options;
const { pattern = new NoopPattern() } = options;
const parser: PatternShape<any> = pattern instanceof NoopPattern ?
pattern : new Pattern(pattern);

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

return {
logs: data.data.result.map((result) => {
return {
stream: result.stream,
values: result.values.flatMap(([, log]) => parser.executeOnLogs([log]))
values: result.values.flatMap(([, log]) => parser.executeOnLogs([log])) as any[]
};
}),
timerange: utils.queryRangeStreamTimeRange(data.data.result)
};
}

async queryRange<T = string>(
async queryRange<T extends LokiPatternType = string>(
logQL: LogQL | string,
options: LokiQueryOptions<T> = {}
): Promise<QueryRangeResponse<T>> {
const { parser = new NoopLogParser<T>() } = options;
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);

Expand All @@ -139,7 +151,7 @@ export class Loki {
}

return {
values: parser.executeOnLogs(inlinedLogs.values),
values: parser.executeOnLogs(inlinedLogs.values) as any[],
timerange: inlinedLogs.timerange
};
}
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from "./class/GrafanaApi.class.js";
export * from "./class/LogParser.class.js";
export * from "./types";
Loading

0 comments on commit 896d910

Please sign in to comment.