Skip to content

Commit 1cc01c4

Browse files
authored
feat: reworks logging (#10)
1 parent b7b9098 commit 1cc01c4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+987
-267
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# environment files
44
.env*
5+
.otel_token
56

67
# compiled output
78
dist

deno.lock

Lines changed: 6 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/guide/core/events.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ export type AccountAddedEvent = z.infer<typeof AccountAddedEvent>;
4040
```
4141

4242
```typescript [Shell]
43-
import { RouteHandler } from "@nimbus/core";
44-
import * as log from "@std/log";
43+
import { getLogger, RouteHandler } from "@nimbus/core";
4544
import {
4645
AccountAddedData,
4746
AccountAddedEvent,
@@ -53,7 +52,9 @@ export const accountAddedHandler: RouteHandler<
5352
> = async (event) => {
5453
await new Promise((resolve) => setTimeout(resolve, 1000));
5554

56-
log.info({ msg: `New account was added: ${event.data.account.name}` });
55+
getLogger().info({
56+
message: `New account was added: ${event.data.account.name}`,
57+
});
5758

5859
// This is just an example.
5960
// Change the code to do what has to be done after an account got added.

docs/guide/core/logging.md

Lines changed: 96 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,126 @@
11
# Logging
22

3-
For logging Nimbus uses the [`@std/log`](https://jsr.io/@std/log) library.
3+
Nimbus provides a very simple logger that enables you to log messages for different severity levels to the console.
44

5-
## Default setup
5+
It is basically a wrapper around the `console` object and the `console.debug()`, `console.info()`, `console.warn()`, `console.error()` and `console.critical()` methods.
66

7-
Nimbus provides a simple function to setup the logger. You can pass in the log level and the format you want to use.
7+
It helps to have consistent logs with important meta information (timestamp, log level,category, error stack traces, etc) across your application.
88

9-
The `pretty` format is recommended for development environments only. In production you should use the `json` format.
9+
No other transports or sinks are supported. As we want to keep the core as lightweight as possible and encourage the use of tools like [OpenTelemetry](https://opentelemetry.io/) to transport logs for monitoring and tracing.
1010

11-
::: code-group
11+
As [Deno supports OpenTelemetry](https://docs.deno.com/runtime/fundamentals/open_telemetry/) out of the box, you can easily transport logs to any other monitoring system without the need to change the code of the application.
1212

13-
```typescript [main.ts]
14-
import { setupLog } from "@nimbus/core";
13+
## Log Levels
1514

16-
setupLog({
17-
logLevel: process.env.LOG_LEVEL,
18-
format: process.env.NODE_ENV === "development" ? "pretty" : "json",
19-
});
20-
```
15+
Nimbus supports the following log levels for logging messages.
2116

22-
```typescript [logExample.ts]
23-
import * as log from "@std/log";
17+
- `debug` - Outputs a `console.debug()`
18+
- `info` - Outputs a `console.info()`
19+
- `warn` - Outputs a `console.warn()`
20+
- `error` - Outputs a `console.error()`
21+
- `critical` - Outputs a `console.error()`
2422

25-
log.info({ msg: "Hello World!" });
23+
Also `silent` can be used in the setup to completely disable log output.
2624

27-
log.warn({ msg: "Ding Dong!" });
25+
## Setup
2826

29-
log.error({ msg: "Ohh no!", error: new Error("Something went wrong!") });
27+
Nimbus provides a simple function to setup the logger. You can pass in the log level and the formatter you want to use.
3028

31-
log.critical({
32-
msg: "It is over, run!",
33-
error: new Error("Something is burning!"),
29+
The `prettyLogFormatter` is recommended for development environments only. In production you should use the `jsonLogFormatter`.
30+
31+
For the pretty formatter the `useConsoleColors` option can be used to enable colors in the console output.
32+
33+
::: code-group
34+
35+
```typescript [main.ts]
36+
import {
37+
jsonLogFormatter,
38+
parseLogLevel,
39+
prettyLogFormatter,
40+
setupLogger,
41+
} from "@nimbus/core";
42+
43+
setupLogger({
44+
logLevel: parseLogLevel(process.env.LOG_LEVEL),
45+
formatter:
46+
process.env.NODE_ENV === "development"
47+
? prettyLogFormatter
48+
: jsonLogFormatter,
49+
useConsoleColors: process.env.NODE_ENV === "development",
3450
});
3551
```
3652

3753
:::
3854

39-
## Advanced Setup
55+
## Usage
56+
57+
The logger can be accessed via the `getLogger` function.
58+
The logger is a singleton and will return the same instance every time it is called.
4059

41-
In case you want to configure the logger in another way you can use the `setup` function from the `@std/log` library. And add `Nimbus` to the loggers object.
60+
To create a new log you can use the `info`, `warn`, `error` or `critical` methods depending on the severity of the message.
4261

43-
View the [@std/log docs](https://jsr.io/@std/log) for all configuration options.
62+
The log input is an object that can contain the following properties:
63+
64+
- `message` - The message to log.
65+
- `correlationId` - An optional correlation ID to keep track of commands, queries, and events that are related to each other.
66+
- `category` - An optional category of the log, useful for grouping logs together.
67+
- `data` - Optional additional data to log, can be an object with any properties.
68+
- `error` - Optional error object to log.
69+
70+
The error object is specified as a dedicated property and not as part of the `data` object to make sure all error properties and the stack trace are preserved and logged correctly.
4471

4572
::: code-group
4673

47-
```typescript [main.ts]
48-
import * as log from "@std/log";
74+
```typescript [logExample.ts]
75+
import { getLogger } from "@nimbus/core";
4976

50-
log.setup({
51-
handlers: {
52-
default: new log.ConsoleHandler("INFO", {
53-
formatter: log.formatters.jsonFormatter,
54-
}),
55-
},
77+
const logger = getLogger();
78+
79+
logger.debug({
80+
message: "Hello World!",
81+
correlationId: "1234567890",
82+
data: { foo: "bar" },
83+
});
84+
85+
logger.info({ message: "Hello World!" });
86+
87+
logger.warn({
88+
category: "MyCategory",
89+
message: "Ding Dong!",
90+
});
91+
92+
logger.error({
93+
message: "Ohh no!",
94+
error: new Error("Something went wrong!"),
95+
});
5696

57-
loggers: {
58-
Nimbus: {
59-
level: "INFO",
60-
handlers: ["default"],
61-
},
97+
logger.critical({
98+
category: "MyCategory",
99+
message: "It is over, run!",
100+
error: new Error("Something is burning!"),
101+
data: {
102+
accountId: "1234567890",
103+
foo: "bar",
62104
},
63105
});
64106
```
65107

66108
:::
109+
110+
## Nimbus Logs
111+
112+
As the various Nimbus features have implemented log statements as well it uses the same logger provided by the `getLogger()` function.
113+
114+
Therefore all log statements from Nimbus will respect the log level and formatter you have configured for the application.
115+
116+
In case you do not configure the logger in your application the Nimbus logs will use the default settings.
117+
118+
## Default Settings
119+
120+
```typescript
121+
const defaultSettings = {
122+
logLevel: "silent",
123+
formatter: jsonLogFormatter,
124+
useConsoleColors: false,
125+
};
126+
```

docs/guide/quickstart.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ To get started with Nimbus you need to install the [@nimbus/core](https://jsr.io
66

77
Nimbus tries to keep dependencies as low as possible, but there are some packages that are necessary to run Nimbus.
88

9-
For type validations Nimbus relies on [Zod](https://zod.dev/).
10-
And for logging the [@std/log](https://jsr.io/@std/log) package is used.
9+
For type safety at runtime Nimbus relies on [Zod](https://zod.dev/).
1110

1211
## Installation
1312

@@ -16,19 +15,19 @@ Depending on your runtime you can install Nimbus with the following commands.
1615
### Deno
1716

1817
```bash
19-
deno add jsr:@nimbus/core npm:zod jsr:@std/log
18+
deno add jsr:@nimbus/core npm:zod
2019
```
2120

2221
### NPM
2322

2423
```bash
2524
npm install zod
26-
npx jsr add @nimbus/core @std/log
25+
npx jsr add @nimbus/core
2726
```
2827

2928
### Bun
3029

3130
```bash
3231
bun add zod
33-
bunx jsr add @nimbus/core @std/log
32+
bunx jsr add @nimbus/core
3433
```

examples/the-expense/deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"tasks": {
33
"dev": "deno run -A --watch src/main.ts",
4+
"dev:otel": "sh start-with-otel.sh",
45
"test": "deno test -A",
56
"database:seed": "deno run -A src/seedCollections.ts"
67
},
@@ -28,7 +29,6 @@
2829
},
2930
"imports": {
3031
"@oak/oak": "jsr:@oak/oak@^17.1.4",
31-
"@std/log": "jsr:@std/log@^0.224.13",
3232
"@tajpouria/cors": "jsr:@tajpouria/cors@^1.2.1",
3333
"mongodb": "npm:mongodb@^6.12.0",
3434
"zod": "npm:zod@^3.24.1"

examples/the-expense/src/account/shell/events/accountAdded.handler.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { RouteHandler } from '@nimbus/core';
2-
import * as log from '@std/log';
1+
import { getLogger, RouteHandler } from '@nimbus/core';
32
import {
43
AccountAddedData,
54
AccountAddedEvent,
@@ -13,7 +12,9 @@ export const accountAddedHandler: RouteHandler<
1312
) => {
1413
await new Promise((resolve) => setTimeout(resolve, 1000));
1514

16-
log.info({ msg: `New account was added: ${event.data.account.name}` });
15+
getLogger().info({
16+
message: `New account was added: ${event.data.account.name}`,
17+
});
1718

1819
return {
1920
statusCode: 200,

examples/the-expense/src/auth/shell/auth.middleware.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { AuthContext } from '@nimbus/core';
1+
import { AuthContext, getLogger } from '@nimbus/core';
22
import type { Context } from '@oak/oak/context';
33
import type { Next } from '@oak/oak/middleware';
4-
import * as log from '@std/log';
54

65
/**
76
* ! NOT FOR PRODUCTION USE
@@ -39,8 +38,11 @@ export const exampleAuthMiddleware = async (
3938
}
4039

4140
await next();
42-
} catch (error) {
43-
log.error(error);
41+
} catch (error: any) {
42+
getLogger().error({
43+
message: 'Failed to authenticate user',
44+
error,
45+
});
4446

4547
ctx.response.status = 401;
4648
ctx.response.body = {

0 commit comments

Comments
 (0)