@rivetkit/effect 0.0.0-sqlite-uds.37f9e48 → 0.0.0-sqlite-profiling-compat.87d61c0
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/dist/Actor.d.ts +3 -2
- package/dist/Actor.d.ts.map +1 -1
- package/dist/Actor.js +2 -2
- package/dist/Actor.js.map +1 -1
- package/dist/Client.d.ts.map +1 -1
- package/dist/Client.js +4 -6
- package/dist/Client.js.map +1 -1
- package/dist/Logger.d.ts +29 -0
- package/dist/Logger.d.ts.map +1 -0
- package/dist/Logger.js +31 -0
- package/dist/Logger.js.map +1 -0
- package/dist/Registry.d.ts +7 -69
- package/dist/Registry.d.ts.map +1 -1
- package/dist/Registry.js +40 -93
- package/dist/Registry.js.map +1 -1
- package/dist/RivetError.d.ts +3 -18
- package/dist/RivetError.d.ts.map +1 -1
- package/dist/RivetError.js +0 -31
- package/dist/RivetError.js.map +1 -1
- package/dist/State.d.ts +56 -92
- package/dist/State.d.ts.map +1 -1
- package/dist/State.js +57 -51
- package/dist/State.js.map +1 -1
- package/dist/internal/ActorInstanceManager.d.ts.map +1 -1
- package/dist/internal/ActorInstanceManager.js +4 -4
- package/dist/internal/ActorInstanceManager.js.map +1 -1
- package/dist/internal/ActorStateAdapter.d.ts +1 -1
- package/dist/internal/ActorStateAdapter.d.ts.map +1 -1
- package/dist/internal/ActorStateAdapter.js +7 -2
- package/dist/internal/ActorStateAdapter.js.map +1 -1
- package/dist/internal/StateOptions.d.ts +0 -1
- package/dist/internal/StateOptions.d.ts.map +1 -1
- package/dist/internal/logging.d.ts +7 -6
- package/dist/internal/logging.d.ts.map +1 -1
- package/dist/internal/logging.js +102 -78
- package/dist/internal/logging.js.map +1 -1
- package/dist/mod.d.ts +1 -1
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +1 -1
- package/dist/mod.js.map +1 -1
- package/package.json +8 -3
- package/src/Actor.test-d.ts +0 -32
- package/src/Actor.ts +4 -29
- package/src/Client.test.ts +18 -21
- package/src/Client.ts +4 -6
- package/src/Logger.ts +43 -0
- package/src/Registry.test.ts +11 -7
- package/src/Registry.ts +50 -116
- package/src/RivetError.test.ts +0 -11
- package/src/RivetError.ts +0 -37
- package/src/State.test.ts +4 -163
- package/src/State.ts +97 -293
- package/src/internal/ActorInstanceManager.ts +10 -4
- package/src/internal/ActorStateAdapter.ts +11 -5
- package/src/internal/StateOptions.ts +0 -4
- package/src/internal/logging.test.ts +88 -65
- package/src/internal/logging.ts +143 -103
- package/src/mod.ts +1 -1
- package/dist/RivetLogger.d.ts +0 -41
- package/dist/RivetLogger.d.ts.map +0 -1
- package/dist/RivetLogger.js +0 -41
- package/dist/RivetLogger.js.map +0 -1
- package/src/RivetLogger.ts +0 -60
|
@@ -77,9 +77,7 @@ export const make = Effect.fnUntraced(function* <
|
|
|
77
77
|
const scope = yield* Scope.make();
|
|
78
78
|
return yield* Effect.gen(function* () {
|
|
79
79
|
const state = stateAdapter
|
|
80
|
-
? yield* stateAdapter
|
|
81
|
-
.makeStateView(c)
|
|
82
|
-
.pipe(Effect.provideService(Scope.Scope, scope))
|
|
80
|
+
? yield* stateAdapter.makeStateView(c)
|
|
83
81
|
: undefined;
|
|
84
82
|
const context = makeContext(c, scope);
|
|
85
83
|
const actionHandlers = yield* wakeHandler(
|
|
@@ -107,7 +105,15 @@ export const make = Effect.fnUntraced(function* <
|
|
|
107
105
|
return {
|
|
108
106
|
get: (actorId: string) => instances.get(actorId),
|
|
109
107
|
onWake: async (c: WakeContext<StateDefinition, Database>) => {
|
|
110
|
-
|
|
108
|
+
await runPromise(
|
|
109
|
+
makeInstance(c).pipe(
|
|
110
|
+
Effect.tap((instance) =>
|
|
111
|
+
Effect.sync(() => {
|
|
112
|
+
instances.set(c.actorId, instance);
|
|
113
|
+
}),
|
|
114
|
+
),
|
|
115
|
+
),
|
|
116
|
+
);
|
|
111
117
|
},
|
|
112
118
|
onStateChange: stateAdapter
|
|
113
119
|
? (
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Effect, type Fiber, Schema } from "effect";
|
|
1
|
+
import { Effect, type Fiber, Schema, Semaphore } from "effect";
|
|
2
2
|
import * as State from "../State.ts";
|
|
3
3
|
import type * as StateOptions from "./StateOptions.ts";
|
|
4
4
|
|
|
5
5
|
export type ActorState<StateDefinition extends StateOptions.Any> = State.State<
|
|
6
6
|
StateOptions.Decoded<StateDefinition>,
|
|
7
|
-
Schema.SchemaError
|
|
8
|
-
StateOptions.Services<StateDefinition>
|
|
7
|
+
Schema.SchemaError
|
|
9
8
|
>;
|
|
10
9
|
|
|
11
10
|
type StateInstance<StateDefinition extends StateOptions.Any> = {
|
|
@@ -72,8 +71,15 @@ export const make = Effect.fnUntraced(function* <
|
|
|
72
71
|
const state = yield* Effect.fromNullishOr(
|
|
73
72
|
instance.state,
|
|
74
73
|
).pipe(Effect.orDie);
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
|
|
75
|
+
yield* Semaphore.withPermit(
|
|
76
|
+
state.semaphore,
|
|
77
|
+
Effect.gen(function* () {
|
|
78
|
+
const decoded = yield* stateCodec
|
|
79
|
+
.decodeUnknown(newState)
|
|
80
|
+
.pipe(Effect.orDie);
|
|
81
|
+
State.publishUnsafe(state, decoded);
|
|
82
|
+
}),
|
|
77
83
|
);
|
|
78
84
|
}),
|
|
79
85
|
);
|
|
@@ -10,10 +10,6 @@ export interface Any {
|
|
|
10
10
|
readonly initialValue: () => unknown;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export type Services<State extends Any> =
|
|
14
|
-
| State["schema"]["DecodingServices"]
|
|
15
|
-
| State["schema"]["EncodingServices"];
|
|
16
|
-
|
|
17
13
|
export type Encoded<State extends Any> =
|
|
18
14
|
| State["schema"]["Encoded"]
|
|
19
15
|
| ([State] extends [never] ? undefined : never);
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { assert, describe, it } from "@effect/vitest";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
Config,
|
|
4
|
+
ConfigProvider,
|
|
5
|
+
Effect,
|
|
6
|
+
Layer,
|
|
7
|
+
Logger as EffectLogger,
|
|
8
|
+
References,
|
|
9
|
+
} from "effect";
|
|
10
|
+
import type { Logger as PinoLogger } from "rivetkit/log";
|
|
4
11
|
import * as Logging from "./logging.ts";
|
|
5
12
|
|
|
6
13
|
type LogEntry = {
|
|
@@ -9,7 +16,7 @@ type LogEntry = {
|
|
|
9
16
|
readonly msg: string | undefined;
|
|
10
17
|
};
|
|
11
18
|
|
|
12
|
-
function makeTestLogger(entries: Array<LogEntry>):
|
|
19
|
+
function makeTestLogger(entries: Array<LogEntry>): PinoLogger {
|
|
13
20
|
const logger: Record<string, unknown> = {};
|
|
14
21
|
for (const level of ["trace", "debug", "info", "warn", "error", "fatal"]) {
|
|
15
22
|
logger[level] = (
|
|
@@ -20,7 +27,7 @@ function makeTestLogger(entries: Array<LogEntry>): RivetkitLog.Logger {
|
|
|
20
27
|
};
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
return logger as unknown as
|
|
30
|
+
return logger as unknown as PinoLogger;
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
describe("internal/logging", () => {
|
|
@@ -58,21 +65,23 @@ describe("internal/logging", () => {
|
|
|
58
65
|
key: "room-1",
|
|
59
66
|
actorId: "actor-1",
|
|
60
67
|
}),
|
|
61
|
-
Effect.provide(
|
|
68
|
+
Effect.provide(
|
|
69
|
+
EffectLogger.layer([Logging.makeEffectLogger(baseLogger)]),
|
|
70
|
+
),
|
|
62
71
|
);
|
|
63
72
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
assert.deepStrictEqual(entries, [
|
|
74
|
+
{
|
|
75
|
+
level: "info",
|
|
76
|
+
fields: {
|
|
77
|
+
roomId: "abc",
|
|
78
|
+
actor: "ChatRoom",
|
|
79
|
+
key: "room-1",
|
|
80
|
+
actorId: "actor-1",
|
|
81
|
+
},
|
|
82
|
+
msg: "room awake",
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
76
85
|
}),
|
|
77
86
|
);
|
|
78
87
|
|
|
@@ -83,7 +92,9 @@ describe("internal/logging", () => {
|
|
|
83
92
|
const error = new Error("room failed to wake");
|
|
84
93
|
|
|
85
94
|
yield* Effect.logError(error).pipe(
|
|
86
|
-
Effect.provide(
|
|
95
|
+
Effect.provide(
|
|
96
|
+
EffectLogger.layer([Logging.makeEffectLogger(baseLogger)]),
|
|
97
|
+
),
|
|
87
98
|
);
|
|
88
99
|
|
|
89
100
|
const entry = entries[0];
|
|
@@ -104,7 +115,9 @@ describe("internal/logging", () => {
|
|
|
104
115
|
actorId: "actor-1",
|
|
105
116
|
action: "SendMessage",
|
|
106
117
|
}).pipe(
|
|
107
|
-
Effect.provide(
|
|
118
|
+
Effect.provide(
|
|
119
|
+
EffectLogger.layer([Logging.makeEffectLogger(baseLogger)]),
|
|
120
|
+
),
|
|
108
121
|
);
|
|
109
122
|
|
|
110
123
|
const entry = entries[0];
|
|
@@ -117,7 +130,17 @@ describe("internal/logging", () => {
|
|
|
117
130
|
}),
|
|
118
131
|
);
|
|
119
132
|
|
|
120
|
-
it.effect(
|
|
133
|
+
it.effect(
|
|
134
|
+
"uses References.MinimumLogLevel when creating the base logger",
|
|
135
|
+
() =>
|
|
136
|
+
Effect.gen(function* () {
|
|
137
|
+
const baseLogger = yield* Logging.makeDefaultBaseLogger;
|
|
138
|
+
|
|
139
|
+
assert.strictEqual(baseLogger.level, "debug");
|
|
140
|
+
}).pipe(Effect.provideService(References.MinimumLogLevel, "Debug")),
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
it.effect("accepts the shared Pino RIVET_LOG_LEVEL values", () =>
|
|
121
144
|
Effect.gen(function* () {
|
|
122
145
|
const baseLogger = yield* Logging.makeDefaultBaseLogger;
|
|
123
146
|
|
|
@@ -134,24 +157,25 @@ describe("internal/logging", () => {
|
|
|
134
157
|
),
|
|
135
158
|
);
|
|
136
159
|
|
|
137
|
-
it.effect("
|
|
160
|
+
it.effect("prefers References.MinimumLogLevel over shared env values", () =>
|
|
138
161
|
Effect.gen(function* () {
|
|
139
162
|
const baseLogger = yield* Logging.makeDefaultBaseLogger;
|
|
140
163
|
|
|
141
164
|
assert.strictEqual(baseLogger.level, "debug");
|
|
142
165
|
}).pipe(
|
|
166
|
+
Effect.provideService(References.MinimumLogLevel, "Debug"),
|
|
143
167
|
Effect.provideService(
|
|
144
168
|
ConfigProvider.ConfigProvider,
|
|
145
169
|
ConfigProvider.fromEnv({
|
|
146
170
|
env: {
|
|
147
|
-
RIVET_LOG_LEVEL: "
|
|
171
|
+
RIVET_LOG_LEVEL: "silent",
|
|
148
172
|
},
|
|
149
173
|
}),
|
|
150
174
|
),
|
|
151
175
|
),
|
|
152
176
|
);
|
|
153
177
|
|
|
154
|
-
it.effect("
|
|
178
|
+
it.effect("preserves an explicit Info minimum log level", () =>
|
|
155
179
|
Effect.gen(function* () {
|
|
156
180
|
const baseLogger = yield* Logging.makeDefaultBaseLogger;
|
|
157
181
|
|
|
@@ -162,45 +186,36 @@ describe("internal/logging", () => {
|
|
|
162
186
|
ConfigProvider.ConfigProvider,
|
|
163
187
|
ConfigProvider.fromEnv({
|
|
164
188
|
env: {
|
|
165
|
-
RIVET_LOG_LEVEL: "
|
|
189
|
+
RIVET_LOG_LEVEL: "silent",
|
|
166
190
|
},
|
|
167
191
|
}),
|
|
168
192
|
),
|
|
169
193
|
),
|
|
170
194
|
);
|
|
171
195
|
|
|
172
|
-
it.effect(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}).pipe(
|
|
178
|
-
Effect.provideService(References.MinimumLogLevel, "Debug"),
|
|
179
|
-
Effect.provideService(
|
|
180
|
-
ConfigProvider.ConfigProvider,
|
|
181
|
-
ConfigProvider.fromEnv({
|
|
182
|
-
env: {},
|
|
183
|
-
}),
|
|
184
|
-
),
|
|
185
|
-
),
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
it.effect("RIVET_LOG_LEVEL overrides References.MinimumLogLevel", () =>
|
|
189
|
-
Effect.gen(function* () {
|
|
190
|
-
const baseLogger = yield* Logging.makeDefaultBaseLogger;
|
|
196
|
+
it.effect(
|
|
197
|
+
"uses Config.logLevel values provided to References.MinimumLogLevel",
|
|
198
|
+
() =>
|
|
199
|
+
Effect.gen(function* () {
|
|
200
|
+
const baseLogger = yield* Logging.makeDefaultBaseLogger;
|
|
191
201
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
assert.strictEqual(baseLogger.level, "trace");
|
|
203
|
+
}).pipe(
|
|
204
|
+
Effect.provide(
|
|
205
|
+
Layer.effect(
|
|
206
|
+
References.MinimumLogLevel,
|
|
207
|
+
Config.logLevel("RIVET_LOG_LEVEL"),
|
|
208
|
+
),
|
|
209
|
+
),
|
|
210
|
+
Effect.provideService(
|
|
211
|
+
ConfigProvider.ConfigProvider,
|
|
212
|
+
ConfigProvider.fromEnv({
|
|
213
|
+
env: {
|
|
214
|
+
RIVET_LOG_LEVEL: "Trace",
|
|
215
|
+
},
|
|
216
|
+
}),
|
|
217
|
+
),
|
|
202
218
|
),
|
|
203
|
-
),
|
|
204
219
|
);
|
|
205
220
|
|
|
206
221
|
it.effect(
|
|
@@ -214,18 +229,19 @@ describe("internal/logging", () => {
|
|
|
214
229
|
Effect.provideService(References.CurrentLogLevel, "Debug"),
|
|
215
230
|
Effect.provideService(References.MinimumLogLevel, "Debug"),
|
|
216
231
|
Effect.provide(
|
|
217
|
-
|
|
232
|
+
EffectLogger.layer([
|
|
233
|
+
Logging.makeEffectLogger(baseLogger),
|
|
234
|
+
]),
|
|
218
235
|
),
|
|
219
236
|
);
|
|
220
237
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
assert.strictEqual(typeof entry.fields.fiberId, "string");
|
|
238
|
+
assert.deepStrictEqual(entries, [
|
|
239
|
+
{
|
|
240
|
+
level: "debug",
|
|
241
|
+
fields: {},
|
|
242
|
+
msg: "plain log",
|
|
243
|
+
},
|
|
244
|
+
]);
|
|
229
245
|
}),
|
|
230
246
|
);
|
|
231
247
|
|
|
@@ -240,7 +256,9 @@ describe("internal/logging", () => {
|
|
|
240
256
|
Effect.provideService(References.CurrentLogLevel, "None"),
|
|
241
257
|
Effect.provideService(References.MinimumLogLevel, "All"),
|
|
242
258
|
Effect.provide(
|
|
243
|
-
|
|
259
|
+
EffectLogger.layer([
|
|
260
|
+
Logging.makeEffectLogger(baseLogger),
|
|
261
|
+
]),
|
|
244
262
|
),
|
|
245
263
|
);
|
|
246
264
|
|
|
@@ -258,13 +276,18 @@ describe("internal/logging", () => {
|
|
|
258
276
|
yield* Effect.logInfo("checkout complete").pipe(
|
|
259
277
|
Effect.withLogSpan("checkout"),
|
|
260
278
|
Effect.provide(
|
|
261
|
-
|
|
279
|
+
EffectLogger.layer([
|
|
280
|
+
Logging.makeEffectLogger(baseLogger),
|
|
281
|
+
]),
|
|
262
282
|
),
|
|
263
283
|
);
|
|
264
284
|
|
|
265
285
|
assert.strictEqual(entries.length, 1);
|
|
266
286
|
assert.strictEqual(entries[0]?.level, "info");
|
|
267
287
|
assert.strictEqual(entries[0]?.msg, "checkout complete");
|
|
288
|
+
assert.deepStrictEqual(Object.keys(entries[0]?.fields ?? {}), [
|
|
289
|
+
"spans",
|
|
290
|
+
]);
|
|
268
291
|
const spans = entries[0]?.fields.spans as
|
|
269
292
|
| Record<string, unknown>
|
|
270
293
|
| undefined;
|
package/src/internal/logging.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Cause,
|
|
2
3
|
Config,
|
|
3
4
|
Context,
|
|
4
5
|
Effect,
|
|
5
|
-
Logger,
|
|
6
|
-
Option,
|
|
7
|
-
Predicate,
|
|
8
|
-
Record as EffectRecord,
|
|
6
|
+
Logger as EffectLogger,
|
|
9
7
|
type LogLevel,
|
|
10
8
|
References,
|
|
11
9
|
} from "effect";
|
|
12
10
|
import type * as Rivetkit from "rivetkit";
|
|
13
|
-
import
|
|
11
|
+
import {
|
|
12
|
+
configureDefaultLogger,
|
|
13
|
+
getBaseLogger,
|
|
14
|
+
type Logger as PinoLogger,
|
|
15
|
+
type LogLevel as PinoLogLevel,
|
|
16
|
+
} from "rivetkit/log";
|
|
14
17
|
|
|
15
18
|
const EMPTY_KEY = "/";
|
|
16
19
|
const KEY_SEPARATOR = "/";
|
|
@@ -21,14 +24,25 @@ type ActorLogContext = {
|
|
|
21
24
|
readonly actorId: string;
|
|
22
25
|
};
|
|
23
26
|
|
|
24
|
-
export class BaseLogger extends Context.Service<
|
|
25
|
-
BaseLogger,
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
export class BaseLogger extends Context.Service<BaseLogger, PinoLogger>()(
|
|
28
|
+
"@rivetkit/effect/Logger/BaseLogger",
|
|
29
|
+
) {}
|
|
30
|
+
|
|
31
|
+
const PinoLevelByEffectLevel: Record<LogLevel.LogLevel, PinoLogLevel> = {
|
|
32
|
+
All: "trace",
|
|
33
|
+
Trace: "trace",
|
|
34
|
+
Debug: "debug",
|
|
35
|
+
Info: "info",
|
|
36
|
+
Warn: "warn",
|
|
37
|
+
Error: "error",
|
|
38
|
+
Fatal: "fatal",
|
|
39
|
+
None: "silent",
|
|
40
|
+
};
|
|
28
41
|
|
|
29
|
-
const
|
|
42
|
+
export const toPinoLevel = (logLevel: LogLevel.LogLevel): PinoLogLevel =>
|
|
43
|
+
PinoLevelByEffectLevel[logLevel];
|
|
30
44
|
|
|
31
|
-
const
|
|
45
|
+
const EffectLevelByPinoLevel: Record<PinoLogLevel, LogLevel.LogLevel> = {
|
|
32
46
|
trace: "Trace",
|
|
33
47
|
debug: "Debug",
|
|
34
48
|
info: "Info",
|
|
@@ -36,54 +50,56 @@ const EffectLevelByRivetkitLevel = {
|
|
|
36
50
|
error: "Error",
|
|
37
51
|
fatal: "Fatal",
|
|
38
52
|
silent: "None",
|
|
39
|
-
}
|
|
40
|
-
RivetkitLog.LogLevel,
|
|
41
|
-
Exclude<LogLevel.LogLevel, "All">
|
|
42
|
-
>;
|
|
43
|
-
|
|
44
|
-
const RivetkitLevelByEffectLevel = {
|
|
45
|
-
...Object.fromEntries(
|
|
46
|
-
RivetkitLogLevels.map((level) => [
|
|
47
|
-
EffectLevelByRivetkitLevel[level],
|
|
48
|
-
level,
|
|
49
|
-
]),
|
|
50
|
-
),
|
|
51
|
-
All: "trace",
|
|
52
|
-
} as Record<LogLevel.LogLevel, RivetkitLog.LogLevel>;
|
|
53
|
+
};
|
|
53
54
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (
|
|
55
|
+
const pinoLogLevelFromEnv = Config.string("RIVET_LOG_LEVEL").pipe(
|
|
56
|
+
Config.map((value) => {
|
|
57
|
+
const pinoLevel = value.toLowerCase();
|
|
58
|
+
if (pinoLevel in EffectLevelByPinoLevel) {
|
|
59
|
+
return EffectLevelByPinoLevel[pinoLevel as PinoLogLevel];
|
|
60
|
+
}
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
maybeRivetLogLevel.value.toLowerCase(),
|
|
61
|
-
);
|
|
62
|
-
return parsed.success ? Option.some(parsed.data) : Option.none();
|
|
62
|
+
return "Info";
|
|
63
63
|
}),
|
|
64
64
|
);
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
? maybeRivetLogLevel.value
|
|
71
|
-
: RivetkitLevelByEffectLevel[yield* References.MinimumLogLevel];
|
|
66
|
+
const logLevelFromEnv = Config.logLevel("RIVET_LOG_LEVEL").pipe(
|
|
67
|
+
Config.orElse(() => pinoLogLevelFromEnv),
|
|
68
|
+
Effect.option,
|
|
69
|
+
);
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
export const makeDefaultBaseLogger: Effect.Effect<PinoLogger> = Effect.gen(
|
|
72
|
+
function* () {
|
|
73
|
+
const context = yield* Effect.context();
|
|
74
|
+
const providedMinimumLogLevel = Context.getOrUndefined(
|
|
75
|
+
context,
|
|
76
|
+
References.MinimumLogLevel,
|
|
75
77
|
);
|
|
76
|
-
|
|
78
|
+
const envLogLevel = yield* logLevelFromEnv;
|
|
79
|
+
const logLevel =
|
|
80
|
+
providedMinimumLogLevel !== undefined
|
|
81
|
+
? providedMinimumLogLevel
|
|
82
|
+
: envLogLevel._tag === "Some"
|
|
83
|
+
? envLogLevel.value
|
|
84
|
+
: yield* References.MinimumLogLevel;
|
|
85
|
+
|
|
86
|
+
return yield* Effect.sync(() => {
|
|
87
|
+
configureDefaultLogger(toPinoLevel(logLevel));
|
|
88
|
+
return getBaseLogger();
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
);
|
|
77
92
|
|
|
78
|
-
export const getOrCreateBaseLogger: Effect.Effect<
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
82
|
-
return
|
|
93
|
+
export const getOrCreateBaseLogger: Effect.Effect<PinoLogger> = Effect.gen(
|
|
94
|
+
function* () {
|
|
95
|
+
const provided = yield* Effect.serviceOption(BaseLogger);
|
|
96
|
+
if (provided._tag === "Some") {
|
|
97
|
+
return provided.value;
|
|
83
98
|
}
|
|
84
99
|
|
|
85
100
|
return yield* makeDefaultBaseLogger;
|
|
86
|
-
}
|
|
101
|
+
},
|
|
102
|
+
);
|
|
87
103
|
|
|
88
104
|
export function makeActorLogAnnotations(context: ActorLogContext): {
|
|
89
105
|
readonly actor: string;
|
|
@@ -115,64 +131,59 @@ export function serializeActorKey(key: Rivetkit.ActorKey): string {
|
|
|
115
131
|
.join(KEY_SEPARATOR);
|
|
116
132
|
}
|
|
117
133
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (options.logLevel === "None") return;
|
|
123
|
-
const rivetkitLevel = RivetkitLevelByEffectLevel[options.logLevel];
|
|
124
|
-
const structured = Logger.formatStructured.log(options);
|
|
125
|
-
const { msg, fields: messageFields } = extractMessage(
|
|
126
|
-
structured.message,
|
|
127
|
-
);
|
|
128
|
-
const fields: Record<string, unknown> = {
|
|
129
|
-
...messageFields,
|
|
130
|
-
...structured.annotations,
|
|
131
|
-
fiberId: structured.fiberId,
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
if (!EffectRecord.isEmptyRecord(structured.spans)) {
|
|
135
|
-
fields.spans = structured.spans;
|
|
136
|
-
}
|
|
137
|
-
if (structured.cause !== undefined) {
|
|
138
|
-
fields.cause = structured.cause;
|
|
139
|
-
}
|
|
134
|
+
function structuredValue(value: unknown): unknown {
|
|
135
|
+
if (value instanceof Error) {
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
140
138
|
|
|
141
|
-
|
|
142
|
-
if (msg === undefined) {
|
|
143
|
-
logger.call(baseLogger, fields);
|
|
144
|
-
} else {
|
|
145
|
-
logger.call(baseLogger, fields, msg);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
139
|
+
return value;
|
|
148
140
|
}
|
|
149
141
|
|
|
150
|
-
function
|
|
142
|
+
function extractMessageAndFields(message: unknown): {
|
|
151
143
|
readonly msg: string | undefined;
|
|
152
144
|
readonly fields: Record<string, unknown>;
|
|
153
145
|
} {
|
|
154
146
|
const values = Array.isArray(message) ? message : [message];
|
|
147
|
+
if (values.length === 0) {
|
|
148
|
+
return { msg: undefined, fields: {} };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const [first, ...rest] = values;
|
|
155
152
|
const fields: Record<string, unknown> = {};
|
|
156
|
-
const args: Array<unknown> = [];
|
|
157
153
|
let msg: string | undefined;
|
|
158
154
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Object.assign(fields, rest);
|
|
170
|
-
if (valueMsg !== undefined) msg = String(valueMsg);
|
|
155
|
+
if (first instanceof Error) {
|
|
156
|
+
fields.error = first;
|
|
157
|
+
msg = first.message;
|
|
158
|
+
} else if (first !== null && typeof first === "object") {
|
|
159
|
+
const firstFields = first as Record<string, unknown>;
|
|
160
|
+
for (const [key, value] of Object.entries(firstFields)) {
|
|
161
|
+
if (key === "msg") {
|
|
162
|
+
if (value !== undefined) {
|
|
163
|
+
msg = String(value);
|
|
164
|
+
}
|
|
171
165
|
} else {
|
|
172
|
-
|
|
166
|
+
fields[key] = structuredValue(value);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} else if (first !== undefined) {
|
|
170
|
+
msg = String(first);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const args: Array<unknown> = [];
|
|
174
|
+
for (const value of rest) {
|
|
175
|
+
if (value instanceof Error) {
|
|
176
|
+
fields.error = value;
|
|
177
|
+
} else if (
|
|
178
|
+
value !== null &&
|
|
179
|
+
typeof value === "object" &&
|
|
180
|
+
!Array.isArray(value)
|
|
181
|
+
) {
|
|
182
|
+
for (const [key, fieldValue] of Object.entries(
|
|
183
|
+
value as Record<string, unknown>,
|
|
184
|
+
)) {
|
|
185
|
+
fields[key] = structuredValue(fieldValue);
|
|
173
186
|
}
|
|
174
|
-
} else if (index === 0) {
|
|
175
|
-
msg = value === undefined ? undefined : String(value);
|
|
176
187
|
} else {
|
|
177
188
|
args.push(value);
|
|
178
189
|
}
|
|
@@ -185,13 +196,42 @@ function extractMessage(message: unknown): {
|
|
|
185
196
|
return { msg, fields };
|
|
186
197
|
}
|
|
187
198
|
|
|
188
|
-
function
|
|
189
|
-
|
|
190
|
-
):
|
|
191
|
-
return (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
199
|
+
export function makeEffectLogger(
|
|
200
|
+
baseLogger: PinoLogger,
|
|
201
|
+
): EffectLogger.Logger<unknown, void> {
|
|
202
|
+
return EffectLogger.make(({ cause, date, fiber, logLevel, message }) => {
|
|
203
|
+
const { msg, fields } = extractMessageAndFields(message);
|
|
204
|
+
|
|
205
|
+
for (const [key, value] of Object.entries(
|
|
206
|
+
fiber.getRef(References.CurrentLogAnnotations),
|
|
207
|
+
)) {
|
|
208
|
+
fields[key] = structuredValue(value);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const spans: Record<string, number> = {};
|
|
212
|
+
for (const [label, startTime] of fiber.getRef(
|
|
213
|
+
References.CurrentLogSpans,
|
|
214
|
+
)) {
|
|
215
|
+
spans[label] = date.getTime() - startTime;
|
|
216
|
+
}
|
|
217
|
+
if (Object.keys(spans).length > 0) {
|
|
218
|
+
fields.spans = spans;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (cause.reasons.length > 0) {
|
|
222
|
+
fields.cause = Cause.pretty(cause);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const pinoLevel = toPinoLevel(logLevel);
|
|
226
|
+
if (pinoLevel === "silent") {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const logger = baseLogger[pinoLevel];
|
|
231
|
+
if (msg === undefined) {
|
|
232
|
+
logger.call(baseLogger, fields);
|
|
233
|
+
} else {
|
|
234
|
+
logger.call(baseLogger, fields, msg);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
197
237
|
}
|
package/src/mod.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * as Action from "./Action.ts";
|
|
2
2
|
export * as Actor from "./Actor.ts";
|
|
3
3
|
export * as Client from "./Client.ts";
|
|
4
|
+
export * as Logger from "./Logger.ts";
|
|
4
5
|
export * as Registry from "./Registry.ts";
|
|
5
|
-
export * as RivetLogger from "./RivetLogger.ts";
|
|
6
6
|
export * as RivetError from "./RivetError.ts";
|
|
7
7
|
export * as State from "./State.ts";
|