ff-serv 0.0.2 → 0.1.1

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/index.cjs CHANGED
@@ -58,7 +58,8 @@ var LoggerType;
58
58
  function create(params) {
59
59
  const logger = (0, import_pino.default)(
60
60
  {
61
- level: params?.level ?? "info",
61
+ level: "trace",
62
+ // Level is managed by Effect, so we set the lowest here
62
63
  serializers: {
63
64
  error: import_pino.default.stdSerializers.errWithCause,
64
65
  err: import_pino.default.stdSerializers.errWithCause
@@ -79,7 +80,7 @@ var LoggerType;
79
80
  }
80
81
  LoggerType2.is = is;
81
82
  })(LoggerType || (LoggerType = {}));
82
- var createInstance = import_effect.Effect.fn(function* (params) {
83
+ var createInstance = (params) => import_effect.Effect.gen(function* () {
83
84
  const isDev = import_effect.Option.getOrNull(
84
85
  yield* import_effect.Config.boolean("DEV").pipe(import_effect.Config.option)
85
86
  );
@@ -104,71 +105,135 @@ var createInstance = import_effect.Effect.fn(function* (params) {
104
105
  }
105
106
  });
106
107
  });
107
- var tag = "ff-serv/logger";
108
- var Logger = class _Logger extends import_effect.Effect.Service()(tag, {
109
- effect: createInstance()
110
- }) {
111
- static create(params) {
112
- return _Logger.make(LoggerType.create(params));
108
+ function extractParams(...[obj, msg]) {
109
+ if (typeof obj === "string") {
110
+ return { message: obj };
113
111
  }
114
- static layer = (params) => import_effect.Layer.effect(
115
- _Logger,
112
+ return { message: msg, attributes: obj };
113
+ }
114
+ function callPino({
115
+ annotations,
116
+ message
117
+ }, call) {
118
+ const entries = import_effect.HashMap.toEntries(annotations);
119
+ if (entries.length > 0) {
120
+ return call(Object.fromEntries(entries), String(message));
121
+ }
122
+ return call(String(message));
123
+ }
124
+ var PinoCtx;
125
+ ((PinoCtx2) => {
126
+ const tag = "ff-serv/Pino";
127
+ function is(obj) {
128
+ return typeof obj === "object" && obj != null && "_tag" in obj && obj._tag === tag;
129
+ }
130
+ PinoCtx2.is = is;
131
+ function create(pino2) {
132
+ return {
133
+ _tag: tag,
134
+ pino: pino2,
135
+ effectLogger: import_effect.Logger.make(({ logLevel, ...input }) => {
136
+ switch (logLevel) {
137
+ case import_effect.LogLevel.Info:
138
+ return callPino(input, pino2.info);
139
+ case import_effect.LogLevel.Debug:
140
+ return callPino(input, pino2.debug);
141
+ case import_effect.LogLevel.Warning:
142
+ return callPino(input, pino2.warn);
143
+ case import_effect.LogLevel.Error:
144
+ case import_effect.LogLevel.Fatal:
145
+ return callPino(input, pino2.error);
146
+ default:
147
+ return callPino(input, pino2.info);
148
+ }
149
+ })
150
+ };
151
+ }
152
+ PinoCtx2.create = create;
153
+ })(PinoCtx || (PinoCtx = {}));
154
+ var Pino = class extends import_effect.Context.Tag("ff-serv/Pino")() {
155
+ };
156
+ var Logger;
157
+ ((Logger2) => {
158
+ Logger2.layer = (opts) => import_effect.Logger.replaceEffect(
159
+ import_effect.Logger.defaultLogger,
116
160
  import_effect.Effect.gen(function* () {
117
- return _Logger.make(yield* createInstance(params));
161
+ return (yield* Pino).effectLogger;
118
162
  })
163
+ ).pipe(
164
+ import_effect.Layer.provideMerge(
165
+ import_effect.Layer.effect(
166
+ Pino,
167
+ import_effect.Effect.gen(function* () {
168
+ return PinoCtx.create(yield* createInstance(opts));
169
+ })
170
+ )
171
+ )
119
172
  );
120
- //
121
- static get = import_effect.Effect.fn(function* () {
122
- const logger = yield* import_effect.Effect.serviceOption(_Logger);
123
- if (import_effect.Option.isNone(logger)) return void 0;
124
- return logger.value;
173
+ Logger2.Default = (0, Logger2.layer)();
174
+ Logger2.sync = () => import_effect.Effect.gen(function* () {
175
+ const pino2 = yield* Pino;
176
+ const runtime = import_effect.ManagedRuntime.make(
177
+ import_effect.Logger.replace(import_effect.Logger.defaultLogger, pino2.effectLogger)
178
+ );
179
+ return {
180
+ info: (...params) => Logger2.info(...params).pipe((e) => runtime.runSync(e)),
181
+ debug: (...params) => Logger2.debug(...params).pipe((e) => runtime.runSync(e)),
182
+ warn: (...params) => Logger2.warn(...params).pipe((e) => runtime.runSync(e)),
183
+ error: (...params) => Logger2.error(...params).pipe((e) => runtime.runSync(e))
184
+ };
125
185
  });
126
- static replace = (logger) => (e) => {
127
- if (logger == null) return e;
128
- if (logger instanceof _Logger)
129
- return import_effect.Effect.provideService(e, _Logger, logger);
130
- if (LoggerType.is(logger)) {
131
- return import_effect.Effect.provideService(e, _Logger, _Logger.make(logger));
132
- }
133
- return import_effect.Effect.provideService(
186
+ Logger2.get = () => Logger2.sync();
187
+ Logger2.replace = (logger) => (e) => import_effect.Effect.gen(function* () {
188
+ const oldPinoCtx = yield* Pino;
189
+ const pino2 = LoggerType.is(logger) ? logger : LoggerType.fromPino(logger);
190
+ const pinoCtx = PinoCtx.create(pino2);
191
+ return yield* import_effect.Effect.provide(
134
192
  e,
135
- _Logger,
136
- _Logger.make(LoggerType.fromPino(logger))
193
+ import_effect.Layer.mergeAll(
194
+ import_effect.Logger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger),
195
+ import_effect.Layer.succeed(Pino, pinoCtx)
196
+ )
137
197
  );
138
- };
139
- static replaceChild = (...params) => (e) => import_effect.Effect.gen(function* () {
140
- const logger = yield* _Logger.get();
141
- if (logger == null) return yield* e;
142
- const child = logger.child(...params);
143
- return yield* import_effect.Effect.provideService(e, _Logger, _Logger.make(child));
144
198
  });
145
- // --
146
- static info = import_effect.Effect.fn(function* (...params) {
147
- const logger = yield* _Logger.get();
148
- if (logger == null) return;
149
- logger.info(...params);
199
+ Logger2.replaceChild = (...params) => (e) => import_effect.Effect.gen(function* () {
200
+ const oldPinoCtx = yield* Pino;
201
+ const pino2 = oldPinoCtx.pino.child(...params);
202
+ const pinoCtx = PinoCtx.create(pino2);
203
+ return yield* import_effect.Effect.provide(
204
+ import_effect.Effect.provide(
205
+ e,
206
+ import_effect.Logger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger)
207
+ ),
208
+ import_effect.Layer.succeed(Pino, pinoCtx)
209
+ );
150
210
  });
151
- static debug = import_effect.Effect.fn(function* (...params) {
152
- const logger = yield* _Logger.get();
153
- if (logger == null) return;
154
- logger.debug(...params);
211
+ Logger2.info = (...params) => import_effect.Effect.gen(function* () {
212
+ const { message, attributes } = extractParams(...params);
213
+ yield* import_effect.Effect.logInfo(message).pipe(
214
+ attributes ? import_effect.Effect.annotateLogs(attributes) : (e) => e
215
+ );
155
216
  });
156
- static warn = import_effect.Effect.fn(function* (...params) {
157
- const logger = yield* _Logger.get();
158
- if (logger == null) return;
159
- logger.warn(...params);
217
+ Logger2.debug = (...params) => import_effect.Effect.gen(function* () {
218
+ const { message, attributes } = extractParams(...params);
219
+ yield* import_effect.Effect.logDebug(message).pipe(
220
+ attributes ? import_effect.Effect.annotateLogs(attributes) : (e) => e
221
+ );
160
222
  });
161
- static error = import_effect.Effect.fn(function* (...params) {
162
- const logger = yield* _Logger.get();
163
- if (logger == null) return;
164
- logger.error(...params);
223
+ Logger2.warn = (...params) => import_effect.Effect.gen(function* () {
224
+ const { message, attributes } = extractParams(...params);
225
+ yield* import_effect.Effect.logWarning(message).pipe(
226
+ attributes ? import_effect.Effect.annotateLogs(attributes) : (e) => e
227
+ );
165
228
  });
166
- static flush = import_effect.Effect.fn(function* (...params) {
167
- const logger = yield* _Logger.get();
168
- if (logger == null) return;
169
- logger.flush(...params);
229
+ Logger2.error = (...params) => import_effect.Effect.gen(function* () {
230
+ const { message, attributes } = extractParams(...params);
231
+ yield* import_effect.Effect.logError(message).pipe(
232
+ attributes ? import_effect.Effect.annotateLogs(attributes) : (e) => e
233
+ );
170
234
  });
171
- };
235
+ Logger2.flush = (..._params) => import_effect.Effect.void;
236
+ })(Logger || (Logger = {}));
172
237
  // Annotate the CommonJS export names for ESM import in node:
173
238
  0 && (module.exports = {
174
239
  Logger
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/logger.ts"],"sourcesContent":["export { Logger } from './logger.js';\n","import { Config, Effect, Layer, Option } from 'effect';\nimport pino from 'pino';\n\n// Base logger\n\nnamespace LoggerType {\n\texport function fromPino(x: pino.Logger<never, boolean>) {\n\t\treturn {\n\t\t\tinfo: x.info.bind(x),\n\t\t\terror: x.error.bind(x),\n\t\t\twarn: x.warn.bind(x),\n\t\t\tdebug: x.debug.bind(x),\n\t\t\tchild: (...params: Parameters<typeof x.child>) => {\n\t\t\t\treturn fromPino(\n\t\t\t\t\tx.child(...params) as unknown as pino.Logger<never, boolean>,\n\t\t\t\t);\n\t\t\t},\n\t\t\tflush: x.flush.bind(x),\n\t\t\t_pino: x,\n\t\t};\n\t}\n\n\texport type CreateParams = {\n\t\tlevel?: pino.Level;\n\t\tstream?: pino.DestinationStream;\n\t};\n\n\texport function create(params?: CreateParams) {\n\t\tconst logger = pino(\n\t\t\t{\n\t\t\t\tlevel: params?.level ?? 'info',\n\t\t\t\tserializers: {\n\t\t\t\t\terror: pino.stdSerializers.errWithCause,\n\t\t\t\t\terr: pino.stdSerializers.errWithCause,\n\t\t\t\t},\n\t\t\t\tformatters: {\n\t\t\t\t\tlevel: (label) => {\n\t\t\t\t\t\treturn { level: label };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams?.stream,\n\t\t);\n\t\treturn fromPino(logger);\n\t}\n\n\texport function is(x: object): x is LoggerType {\n\t\treturn '_pino' in x;\n\t}\n}\ntype LoggerType = ReturnType<typeof LoggerType.create>;\n\n// Effect service\nconst createInstance = Effect.fn(function* (params?: LoggerType.CreateParams) {\n\tconst isDev = Option.getOrNull(\n\t\tyield* Config.boolean('DEV').pipe(Config.option),\n\t);\n\tconst logFile = Option.getOrNull(\n\t\tyield* Config.boolean('LOGGER_LOGFILE').pipe(Config.option),\n\t);\n\n\treturn LoggerType.create({\n\t\t...params,\n\t\t...(isDev && {\n\t\t\tstream: logFile\n\t\t\t\t? pino.transport({\n\t\t\t\t\t\ttarget: 'pino/file',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tdestination: './logs/server.log',\n\t\t\t\t\t\t\tmkdir: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t: pino.transport({\n\t\t\t\t\t\ttarget: 'pino-pretty',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tignore: 'pid,hostname',\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t}),\n\t});\n});\n\nconst tag = 'ff-serv/logger' as const;\nexport class Logger extends Effect.Service<Logger>()(tag, {\n\teffect: createInstance(),\n}) {\n\tstatic create(params?: LoggerType.CreateParams) {\n\t\treturn Logger.make(LoggerType.create(params));\n\t}\n\n\tstatic layer = (params?: Parameters<typeof createInstance>[0]) =>\n\t\tLayer.effect(\n\t\t\tLogger,\n\t\t\tEffect.gen(function* () {\n\t\t\t\treturn Logger.make(yield* createInstance(params));\n\t\t\t}),\n\t\t);\n\n\t//\n\n\tstatic get = Effect.fn(function* () {\n\t\tconst logger = yield* Effect.serviceOption(Logger);\n\t\tif (Option.isNone(logger)) return undefined;\n\t\treturn logger.value;\n\t});\n\n\tstatic replace =\n\t\t(logger: Logger | LoggerType | pino.Logger | undefined) =>\n\t\t<A, E, R>(e: Effect.Effect<A, E, R>) => {\n\t\t\tif (logger == null) return e;\n\t\t\tif (logger instanceof Logger)\n\t\t\t\treturn Effect.provideService(e, Logger, logger);\n\n\t\t\tif (LoggerType.is(logger)) {\n\t\t\t\treturn Effect.provideService(e, Logger, Logger.make(logger));\n\t\t\t}\n\n\t\t\treturn Effect.provideService(\n\t\t\t\te,\n\t\t\t\tLogger,\n\t\t\t\tLogger.make(LoggerType.fromPino(logger)),\n\t\t\t);\n\t\t};\n\n\tstatic replaceChild =\n\t\t(...params: Parameters<LoggerType['child']>) =>\n\t\t<A, E, R>(e: Effect.Effect<A, E, R>) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst logger = yield* Logger.get();\n\t\t\t\tif (logger == null) return yield* e;\n\n\t\t\t\tconst child = logger.child(...params);\n\t\t\t\treturn yield* Effect.provideService(e, Logger, Logger.make(child));\n\t\t\t});\n\n\t// --\n\n\tstatic info = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['info']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.info(...params);\n\t});\n\n\tstatic debug = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['debug']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.debug(...params);\n\t});\n\n\tstatic warn = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['warn']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.warn(...params);\n\t});\n\n\tstatic error = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['error']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.error(...params);\n\t});\n\n\tstatic flush = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['flush']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.flush(...params);\n\t});\n}\n"],"mappings":"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","names":["LoggerType","pino"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/logger.ts"],"sourcesContent":["export { Logger } from './logger.js';\n","import {\n\tConfig,\n\tContext,\n\tEffect,\n\tLogger as EffectLogger,\n\tHashMap,\n\tLayer,\n\tLogLevel,\n\tManagedRuntime,\n\tOption,\n} from 'effect';\nimport pino from 'pino';\n\n// Pino Instance\n\nnamespace LoggerType {\n\texport function fromPino(x: pino.Logger<never, boolean>) {\n\t\treturn {\n\t\t\tinfo: x.info.bind(x),\n\t\t\terror: x.error.bind(x),\n\t\t\twarn: x.warn.bind(x),\n\t\t\tdebug: x.debug.bind(x),\n\t\t\tchild: (...params: Parameters<typeof x.child>) => {\n\t\t\t\treturn fromPino(\n\t\t\t\t\tx.child(...params) as unknown as pino.Logger<never, boolean>,\n\t\t\t\t);\n\t\t\t},\n\t\t\tflush: x.flush.bind(x),\n\t\t\t_pino: x,\n\t\t};\n\t}\n\n\texport type CreateParams = {\n\t\tstream?: pino.DestinationStream;\n\t};\n\n\texport function create(params?: CreateParams) {\n\t\tconst logger = pino(\n\t\t\t{\n\t\t\t\tlevel: 'trace', // Level is managed by Effect, so we set the lowest here\n\t\t\t\tserializers: {\n\t\t\t\t\terror: pino.stdSerializers.errWithCause,\n\t\t\t\t\terr: pino.stdSerializers.errWithCause,\n\t\t\t\t},\n\t\t\t\tformatters: {\n\t\t\t\t\tlevel: (label) => {\n\t\t\t\t\t\treturn { level: label };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams?.stream,\n\t\t);\n\t\treturn fromPino(logger);\n\t}\n\n\texport type Type = ReturnType<typeof LoggerType.create>;\n\n\texport function is(x: object): x is Type {\n\t\treturn '_pino' in x;\n\t}\n}\ntype LoggerType = LoggerType.Type;\n\n// The Gist\n\nconst createInstance = (params?: LoggerType.CreateParams) =>\n\tEffect.gen(function* () {\n\t\tconst isDev = Option.getOrNull(\n\t\t\tyield* Config.boolean('DEV').pipe(Config.option),\n\t\t);\n\t\tconst logFile = Option.getOrNull(\n\t\t\tyield* Config.boolean('LOGGER_LOGFILE').pipe(Config.option),\n\t\t);\n\n\t\treturn LoggerType.create({\n\t\t\t...params,\n\t\t\t...(isDev && {\n\t\t\t\tstream: logFile\n\t\t\t\t\t? pino.transport({\n\t\t\t\t\t\t\ttarget: 'pino/file',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tdestination: './logs/server.log',\n\t\t\t\t\t\t\t\tmkdir: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t: pino.transport({\n\t\t\t\t\t\t\ttarget: 'pino-pretty',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tignore: 'pid,hostname',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t}),\n\t\t});\n\t});\n\n// Pino Context and Effect Logger integration\n\ntype LogParams = [obj: unknown, msg?: string];\nfunction extractParams(...[obj, msg]: LogParams) {\n\tif (typeof obj === 'string') {\n\t\treturn { message: obj };\n\t}\n\treturn { message: msg, attributes: obj as Record<string, any> };\n}\n\n/** A simple helper for calling pino log functions */\nfunction callPino(\n\t{\n\t\tannotations,\n\t\tmessage,\n\t}: Pick<EffectLogger.Logger.Options<unknown>, 'annotations' | 'message'>,\n\tcall: (...params: [obj: unknown, msg?: string]) => void,\n) {\n\tconst entries = HashMap.toEntries(annotations);\n\tif (entries.length > 0) {\n\t\treturn call(Object.fromEntries(entries), String(message));\n\t}\n\n\treturn call(String(message));\n}\n\nnamespace PinoCtx {\n\tconst tag = 'ff-serv/Pino';\n\texport type Type = ReturnType<typeof create>;\n\n\texport function is(obj: unknown): obj is Type {\n\t\treturn (\n\t\t\ttypeof obj === 'object' &&\n\t\t\tobj != null &&\n\t\t\t'_tag' in obj &&\n\t\t\tobj._tag === tag\n\t\t);\n\t}\n\n\texport function create(pino: LoggerType) {\n\t\treturn {\n\t\t\t_tag: tag,\n\t\t\tpino,\n\t\t\teffectLogger: EffectLogger.make(({ logLevel, ...input }) => {\n\t\t\t\tswitch (logLevel) {\n\t\t\t\t\tcase LogLevel.Info:\n\t\t\t\t\t\treturn callPino(input, pino.info);\n\t\t\t\t\tcase LogLevel.Debug:\n\t\t\t\t\t\treturn callPino(input, pino.debug);\n\t\t\t\t\tcase LogLevel.Warning:\n\t\t\t\t\t\treturn callPino(input, pino.warn);\n\t\t\t\t\tcase LogLevel.Error:\n\t\t\t\t\tcase LogLevel.Fatal:\n\t\t\t\t\t\treturn callPino(input, pino.error);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn callPino(input, pino.info);\n\t\t\t\t}\n\t\t\t}),\n\t\t};\n\t}\n}\ntype PinoCtx = PinoCtx.Type;\n\nclass Pino extends Context.Tag('ff-serv/Pino')<Pino, PinoCtx>() {}\n\n// Facade\n\nexport namespace Logger {\n\texport const layer = (opts?: Parameters<typeof createInstance>[0]) =>\n\t\tEffectLogger.replaceEffect(\n\t\t\tEffectLogger.defaultLogger,\n\t\t\tEffect.gen(function* () {\n\t\t\t\treturn (yield* Pino).effectLogger;\n\t\t\t}),\n\t\t).pipe(\n\t\t\tLayer.provideMerge(\n\t\t\t\tLayer.effect(\n\t\t\t\t\tPino,\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\treturn PinoCtx.create(yield* createInstance(opts));\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\texport const Default = layer();\n\n\t//\n\n\texport const sync = () =>\n\t\tEffect.gen(function* () {\n\t\t\tconst pino = yield* Pino;\n\t\t\tconst runtime = ManagedRuntime.make(\n\t\t\t\tEffectLogger.replace(EffectLogger.defaultLogger, pino.effectLogger),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tinfo: (...params: Parameters<typeof Logger.info>) =>\n\t\t\t\t\tLogger.info(...params).pipe((e) => runtime.runSync(e)),\n\t\t\t\tdebug: (...params: Parameters<typeof Logger.debug>) =>\n\t\t\t\t\tLogger.debug(...params).pipe((e) => runtime.runSync(e)),\n\t\t\t\twarn: (...params: Parameters<typeof Logger.warn>) =>\n\t\t\t\t\tLogger.warn(...params).pipe((e) => runtime.runSync(e)),\n\t\t\t\terror: (...params: Parameters<typeof Logger.error>) =>\n\t\t\t\t\tLogger.error(...params).pipe((e) => runtime.runSync(e)),\n\t\t\t};\n\t\t});\n\n\t/** @deprecated — will be renamed to `sync` */\n\texport const get = () => Logger.sync();\n\n\texport const replace =\n\t\t(logger: LoggerType | pino.Logger) =>\n\t\t<A, E, R>(e: Effect.Effect<A, E, R>) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst oldPinoCtx = yield* Pino;\n\t\t\t\tconst pino = LoggerType.is(logger)\n\t\t\t\t\t? logger\n\t\t\t\t\t: LoggerType.fromPino(logger);\n\t\t\t\tconst pinoCtx = PinoCtx.create(pino);\n\n\t\t\t\treturn yield* Effect.provide(\n\t\t\t\t\te,\n\t\t\t\t\tLayer.mergeAll(\n\t\t\t\t\t\tEffectLogger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger),\n\t\t\t\t\t\tLayer.succeed(Pino, pinoCtx),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t});\n\n\texport const replaceChild =\n\t\t(...params: Parameters<LoggerType['child']>) =>\n\t\t<A, E, R>(e: Effect.Effect<A, E, R>) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst oldPinoCtx = yield* Pino;\n\t\t\t\tconst pino = oldPinoCtx.pino.child(...params);\n\t\t\t\tconst pinoCtx = PinoCtx.create(pino);\n\n\t\t\t\treturn yield* Effect.provide(\n\t\t\t\t\tEffect.provide(\n\t\t\t\t\t\te,\n\t\t\t\t\t\tEffectLogger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger),\n\t\t\t\t\t),\n\t\t\t\t\tLayer.succeed(Pino, pinoCtx),\n\t\t\t\t);\n\t\t\t});\n\n\t// --\n\n\texport const info = (...params: LogParams) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst { message, attributes } = extractParams(...params);\n\t\t\tyield* Effect.logInfo(message).pipe(\n\t\t\t\tattributes ? Effect.annotateLogs(attributes) : (e) => e,\n\t\t\t);\n\t\t});\n\n\texport const debug = (...params: LogParams) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst { message, attributes } = extractParams(...params);\n\t\t\tyield* Effect.logDebug(message).pipe(\n\t\t\t\tattributes ? Effect.annotateLogs(attributes) : (e) => e,\n\t\t\t);\n\t\t});\n\n\texport const warn = (...params: LogParams) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst { message, attributes } = extractParams(...params);\n\t\t\tyield* Effect.logWarning(message).pipe(\n\t\t\t\tattributes ? Effect.annotateLogs(attributes) : (e) => e,\n\t\t\t);\n\t\t});\n\n\texport const error = (...params: LogParams) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst { message, attributes } = extractParams(...params);\n\t\t\tyield* Effect.logError(message).pipe(\n\t\t\t\tattributes ? Effect.annotateLogs(attributes) : (e) => e,\n\t\t\t);\n\t\t});\n\n\t/** @deprecated */\n\texport const flush = (..._params: Parameters<LoggerType['flush']>) =>\n\t\tEffect.void;\n}\n"],"mappings":"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","names":["LoggerType","pino","PinoCtx","EffectLogger","Logger"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as effect_ConfigError from 'effect/ConfigError';
2
- import { Effect, Layer } from 'effect';
2
+ import { Effect, Layer, Context, Logger as Logger$1 } from 'effect';
3
3
  import pino from 'pino';
4
4
 
5
5
  declare namespace LoggerType {
@@ -13,7 +13,6 @@ declare namespace LoggerType {
13
13
  _pino: pino.Logger<never, boolean>;
14
14
  };
15
15
  type CreateParams = {
16
- level?: pino.Level;
17
16
  stream?: pino.DestinationStream;
18
17
  };
19
18
  function create(params?: CreateParams): {
@@ -25,10 +24,11 @@ declare namespace LoggerType {
25
24
  flush: (cb?: (err?: Error) => void) => void;
26
25
  _pino: pino.Logger<never, boolean>;
27
26
  };
28
- function is(x: object): x is LoggerType;
27
+ type Type = ReturnType<typeof LoggerType.create>;
28
+ function is(x: object): x is Type;
29
29
  }
30
- type LoggerType = ReturnType<typeof LoggerType.create>;
31
- declare const createInstance: (params?: LoggerType.CreateParams | undefined) => Effect.Effect<{
30
+ type LoggerType = LoggerType.Type;
31
+ declare const createInstance: (params?: LoggerType.CreateParams) => Effect.Effect<{
32
32
  info: pino.LogFn;
33
33
  error: pino.LogFn;
34
34
  warn: pino.LogFn;
@@ -37,8 +37,10 @@ declare const createInstance: (params?: LoggerType.CreateParams | undefined) =>
37
37
  flush: (cb?: (err?: Error) => void) => void;
38
38
  _pino: pino.Logger<never, boolean>;
39
39
  }, effect_ConfigError.ConfigError, never>;
40
- declare const Logger_base: Effect.Service.Class<Logger, "ff-serv/logger", {
41
- readonly effect: Effect.Effect<{
40
+ type LogParams = [obj: unknown, msg?: string];
41
+ declare const Pino_base: Context.TagClass<Pino, "ff-serv/Pino", {
42
+ _tag: string;
43
+ pino: {
42
44
  info: pino.LogFn;
43
45
  error: pino.LogFn;
44
46
  warn: pino.LogFn;
@@ -46,19 +48,35 @@ declare const Logger_base: Effect.Service.Class<Logger, "ff-serv/logger", {
46
48
  child: (bindings: pino.Bindings, options?: pino.ChildLoggerOptions<string> | undefined) => /*elided*/ any;
47
49
  flush: (cb?: (err?: Error) => void) => void;
48
50
  _pino: pino.Logger<never, boolean>;
49
- }, effect_ConfigError.ConfigError, never>;
51
+ };
52
+ effectLogger: Logger$1.Logger<unknown, void>;
50
53
  }>;
51
- declare class Logger extends Logger_base {
52
- static create(params?: LoggerType.CreateParams): Logger;
53
- static layer: (params?: Parameters<typeof createInstance>[0]) => Layer.Layer<Logger, effect_ConfigError.ConfigError, never>;
54
- static get: () => Effect.Effect<Logger | undefined, never, never>;
55
- static replace: (logger: Logger | LoggerType | pino.Logger | undefined) => <A, E, R>(e: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
56
- static replaceChild: (...params: Parameters<LoggerType["child"]>) => <A, E, R>(e: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
57
- static info: (obj: unknown, msg?: string | undefined, ...args: unknown[]) => Effect.Effect<void, never, never>;
58
- static debug: (obj: unknown, msg?: string | undefined, ...args: unknown[]) => Effect.Effect<void, never, never>;
59
- static warn: (obj: unknown, msg?: string | undefined, ...args: unknown[]) => Effect.Effect<void, never, never>;
60
- static error: (obj: unknown, msg?: string | undefined, ...args: unknown[]) => Effect.Effect<void, never, never>;
61
- static flush: (cb?: ((err?: Error) => void) | undefined) => Effect.Effect<void, never, never>;
54
+ declare class Pino extends Pino_base {
55
+ }
56
+ declare namespace Logger {
57
+ const layer: (opts?: Parameters<typeof createInstance>[0]) => Layer.Layer<Pino, effect_ConfigError.ConfigError, never>;
58
+ const Default: Layer.Layer<Pino, effect_ConfigError.ConfigError, never>;
59
+ const sync: () => Effect.Effect<{
60
+ info: (obj: unknown, msg?: string | undefined) => void;
61
+ debug: (obj: unknown, msg?: string | undefined) => void;
62
+ warn: (obj: unknown, msg?: string | undefined) => void;
63
+ error: (obj: unknown, msg?: string | undefined) => void;
64
+ }, never, Pino>;
65
+ /** @deprecated — will be renamed to `sync` */
66
+ const get: () => Effect.Effect<{
67
+ info: (obj: unknown, msg?: string | undefined) => void;
68
+ debug: (obj: unknown, msg?: string | undefined) => void;
69
+ warn: (obj: unknown, msg?: string | undefined) => void;
70
+ error: (obj: unknown, msg?: string | undefined) => void;
71
+ }, never, Pino>;
72
+ const replace: (logger: LoggerType | pino.Logger) => <A, E, R>(e: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Pino | Exclude<R, Pino>>;
73
+ const replaceChild: (...params: Parameters<LoggerType["child"]>) => <A, E, R>(e: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Pino | Exclude<Exclude<R, never>, Pino>>;
74
+ const info: (...params: LogParams) => Effect.Effect<void, never, never>;
75
+ const debug: (...params: LogParams) => Effect.Effect<void, never, never>;
76
+ const warn: (...params: LogParams) => Effect.Effect<void, never, never>;
77
+ const error: (...params: LogParams) => Effect.Effect<void, never, never>;
78
+ /** @deprecated */
79
+ const flush: (..._params: Parameters<LoggerType["flush"]>) => Effect.Effect<void, never, never>;
62
80
  }
63
81
 
64
82
  export { Logger };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as effect_ConfigError from 'effect/ConfigError';
2
- import { Effect, Layer } from 'effect';
2
+ import { Effect, Layer, Context, Logger as Logger$1 } from 'effect';
3
3
  import pino from 'pino';
4
4
 
5
5
  declare namespace LoggerType {
@@ -13,7 +13,6 @@ declare namespace LoggerType {
13
13
  _pino: pino.Logger<never, boolean>;
14
14
  };
15
15
  type CreateParams = {
16
- level?: pino.Level;
17
16
  stream?: pino.DestinationStream;
18
17
  };
19
18
  function create(params?: CreateParams): {
@@ -25,10 +24,11 @@ declare namespace LoggerType {
25
24
  flush: (cb?: (err?: Error) => void) => void;
26
25
  _pino: pino.Logger<never, boolean>;
27
26
  };
28
- function is(x: object): x is LoggerType;
27
+ type Type = ReturnType<typeof LoggerType.create>;
28
+ function is(x: object): x is Type;
29
29
  }
30
- type LoggerType = ReturnType<typeof LoggerType.create>;
31
- declare const createInstance: (params?: LoggerType.CreateParams | undefined) => Effect.Effect<{
30
+ type LoggerType = LoggerType.Type;
31
+ declare const createInstance: (params?: LoggerType.CreateParams) => Effect.Effect<{
32
32
  info: pino.LogFn;
33
33
  error: pino.LogFn;
34
34
  warn: pino.LogFn;
@@ -37,8 +37,10 @@ declare const createInstance: (params?: LoggerType.CreateParams | undefined) =>
37
37
  flush: (cb?: (err?: Error) => void) => void;
38
38
  _pino: pino.Logger<never, boolean>;
39
39
  }, effect_ConfigError.ConfigError, never>;
40
- declare const Logger_base: Effect.Service.Class<Logger, "ff-serv/logger", {
41
- readonly effect: Effect.Effect<{
40
+ type LogParams = [obj: unknown, msg?: string];
41
+ declare const Pino_base: Context.TagClass<Pino, "ff-serv/Pino", {
42
+ _tag: string;
43
+ pino: {
42
44
  info: pino.LogFn;
43
45
  error: pino.LogFn;
44
46
  warn: pino.LogFn;
@@ -46,19 +48,35 @@ declare const Logger_base: Effect.Service.Class<Logger, "ff-serv/logger", {
46
48
  child: (bindings: pino.Bindings, options?: pino.ChildLoggerOptions<string> | undefined) => /*elided*/ any;
47
49
  flush: (cb?: (err?: Error) => void) => void;
48
50
  _pino: pino.Logger<never, boolean>;
49
- }, effect_ConfigError.ConfigError, never>;
51
+ };
52
+ effectLogger: Logger$1.Logger<unknown, void>;
50
53
  }>;
51
- declare class Logger extends Logger_base {
52
- static create(params?: LoggerType.CreateParams): Logger;
53
- static layer: (params?: Parameters<typeof createInstance>[0]) => Layer.Layer<Logger, effect_ConfigError.ConfigError, never>;
54
- static get: () => Effect.Effect<Logger | undefined, never, never>;
55
- static replace: (logger: Logger | LoggerType | pino.Logger | undefined) => <A, E, R>(e: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
56
- static replaceChild: (...params: Parameters<LoggerType["child"]>) => <A, E, R>(e: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
57
- static info: (obj: unknown, msg?: string | undefined, ...args: unknown[]) => Effect.Effect<void, never, never>;
58
- static debug: (obj: unknown, msg?: string | undefined, ...args: unknown[]) => Effect.Effect<void, never, never>;
59
- static warn: (obj: unknown, msg?: string | undefined, ...args: unknown[]) => Effect.Effect<void, never, never>;
60
- static error: (obj: unknown, msg?: string | undefined, ...args: unknown[]) => Effect.Effect<void, never, never>;
61
- static flush: (cb?: ((err?: Error) => void) | undefined) => Effect.Effect<void, never, never>;
54
+ declare class Pino extends Pino_base {
55
+ }
56
+ declare namespace Logger {
57
+ const layer: (opts?: Parameters<typeof createInstance>[0]) => Layer.Layer<Pino, effect_ConfigError.ConfigError, never>;
58
+ const Default: Layer.Layer<Pino, effect_ConfigError.ConfigError, never>;
59
+ const sync: () => Effect.Effect<{
60
+ info: (obj: unknown, msg?: string | undefined) => void;
61
+ debug: (obj: unknown, msg?: string | undefined) => void;
62
+ warn: (obj: unknown, msg?: string | undefined) => void;
63
+ error: (obj: unknown, msg?: string | undefined) => void;
64
+ }, never, Pino>;
65
+ /** @deprecated — will be renamed to `sync` */
66
+ const get: () => Effect.Effect<{
67
+ info: (obj: unknown, msg?: string | undefined) => void;
68
+ debug: (obj: unknown, msg?: string | undefined) => void;
69
+ warn: (obj: unknown, msg?: string | undefined) => void;
70
+ error: (obj: unknown, msg?: string | undefined) => void;
71
+ }, never, Pino>;
72
+ const replace: (logger: LoggerType | pino.Logger) => <A, E, R>(e: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Pino | Exclude<R, Pino>>;
73
+ const replaceChild: (...params: Parameters<LoggerType["child"]>) => <A, E, R>(e: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Pino | Exclude<Exclude<R, never>, Pino>>;
74
+ const info: (...params: LogParams) => Effect.Effect<void, never, never>;
75
+ const debug: (...params: LogParams) => Effect.Effect<void, never, never>;
76
+ const warn: (...params: LogParams) => Effect.Effect<void, never, never>;
77
+ const error: (...params: LogParams) => Effect.Effect<void, never, never>;
78
+ /** @deprecated */
79
+ const flush: (..._params: Parameters<LoggerType["flush"]>) => Effect.Effect<void, never, never>;
62
80
  }
63
81
 
64
82
  export { Logger };
package/dist/index.js CHANGED
@@ -1,5 +1,15 @@
1
1
  // src/logger.ts
2
- import { Config, Effect, Layer, Option } from "effect";
2
+ import {
3
+ Config,
4
+ Context,
5
+ Effect,
6
+ Logger as EffectLogger,
7
+ HashMap,
8
+ Layer,
9
+ LogLevel,
10
+ ManagedRuntime,
11
+ Option
12
+ } from "effect";
3
13
  import pino from "pino";
4
14
  var LoggerType;
5
15
  ((LoggerType2) => {
@@ -22,7 +32,8 @@ var LoggerType;
22
32
  function create(params) {
23
33
  const logger = pino(
24
34
  {
25
- level: params?.level ?? "info",
35
+ level: "trace",
36
+ // Level is managed by Effect, so we set the lowest here
26
37
  serializers: {
27
38
  error: pino.stdSerializers.errWithCause,
28
39
  err: pino.stdSerializers.errWithCause
@@ -43,7 +54,7 @@ var LoggerType;
43
54
  }
44
55
  LoggerType2.is = is;
45
56
  })(LoggerType || (LoggerType = {}));
46
- var createInstance = Effect.fn(function* (params) {
57
+ var createInstance = (params) => Effect.gen(function* () {
47
58
  const isDev = Option.getOrNull(
48
59
  yield* Config.boolean("DEV").pipe(Config.option)
49
60
  );
@@ -68,71 +79,135 @@ var createInstance = Effect.fn(function* (params) {
68
79
  }
69
80
  });
70
81
  });
71
- var tag = "ff-serv/logger";
72
- var Logger = class _Logger extends Effect.Service()(tag, {
73
- effect: createInstance()
74
- }) {
75
- static create(params) {
76
- return _Logger.make(LoggerType.create(params));
82
+ function extractParams(...[obj, msg]) {
83
+ if (typeof obj === "string") {
84
+ return { message: obj };
77
85
  }
78
- static layer = (params) => Layer.effect(
79
- _Logger,
86
+ return { message: msg, attributes: obj };
87
+ }
88
+ function callPino({
89
+ annotations,
90
+ message
91
+ }, call) {
92
+ const entries = HashMap.toEntries(annotations);
93
+ if (entries.length > 0) {
94
+ return call(Object.fromEntries(entries), String(message));
95
+ }
96
+ return call(String(message));
97
+ }
98
+ var PinoCtx;
99
+ ((PinoCtx2) => {
100
+ const tag = "ff-serv/Pino";
101
+ function is(obj) {
102
+ return typeof obj === "object" && obj != null && "_tag" in obj && obj._tag === tag;
103
+ }
104
+ PinoCtx2.is = is;
105
+ function create(pino2) {
106
+ return {
107
+ _tag: tag,
108
+ pino: pino2,
109
+ effectLogger: EffectLogger.make(({ logLevel, ...input }) => {
110
+ switch (logLevel) {
111
+ case LogLevel.Info:
112
+ return callPino(input, pino2.info);
113
+ case LogLevel.Debug:
114
+ return callPino(input, pino2.debug);
115
+ case LogLevel.Warning:
116
+ return callPino(input, pino2.warn);
117
+ case LogLevel.Error:
118
+ case LogLevel.Fatal:
119
+ return callPino(input, pino2.error);
120
+ default:
121
+ return callPino(input, pino2.info);
122
+ }
123
+ })
124
+ };
125
+ }
126
+ PinoCtx2.create = create;
127
+ })(PinoCtx || (PinoCtx = {}));
128
+ var Pino = class extends Context.Tag("ff-serv/Pino")() {
129
+ };
130
+ var Logger;
131
+ ((Logger2) => {
132
+ Logger2.layer = (opts) => EffectLogger.replaceEffect(
133
+ EffectLogger.defaultLogger,
80
134
  Effect.gen(function* () {
81
- return _Logger.make(yield* createInstance(params));
135
+ return (yield* Pino).effectLogger;
82
136
  })
137
+ ).pipe(
138
+ Layer.provideMerge(
139
+ Layer.effect(
140
+ Pino,
141
+ Effect.gen(function* () {
142
+ return PinoCtx.create(yield* createInstance(opts));
143
+ })
144
+ )
145
+ )
83
146
  );
84
- //
85
- static get = Effect.fn(function* () {
86
- const logger = yield* Effect.serviceOption(_Logger);
87
- if (Option.isNone(logger)) return void 0;
88
- return logger.value;
147
+ Logger2.Default = (0, Logger2.layer)();
148
+ Logger2.sync = () => Effect.gen(function* () {
149
+ const pino2 = yield* Pino;
150
+ const runtime = ManagedRuntime.make(
151
+ EffectLogger.replace(EffectLogger.defaultLogger, pino2.effectLogger)
152
+ );
153
+ return {
154
+ info: (...params) => Logger2.info(...params).pipe((e) => runtime.runSync(e)),
155
+ debug: (...params) => Logger2.debug(...params).pipe((e) => runtime.runSync(e)),
156
+ warn: (...params) => Logger2.warn(...params).pipe((e) => runtime.runSync(e)),
157
+ error: (...params) => Logger2.error(...params).pipe((e) => runtime.runSync(e))
158
+ };
89
159
  });
90
- static replace = (logger) => (e) => {
91
- if (logger == null) return e;
92
- if (logger instanceof _Logger)
93
- return Effect.provideService(e, _Logger, logger);
94
- if (LoggerType.is(logger)) {
95
- return Effect.provideService(e, _Logger, _Logger.make(logger));
96
- }
97
- return Effect.provideService(
160
+ Logger2.get = () => Logger2.sync();
161
+ Logger2.replace = (logger) => (e) => Effect.gen(function* () {
162
+ const oldPinoCtx = yield* Pino;
163
+ const pino2 = LoggerType.is(logger) ? logger : LoggerType.fromPino(logger);
164
+ const pinoCtx = PinoCtx.create(pino2);
165
+ return yield* Effect.provide(
98
166
  e,
99
- _Logger,
100
- _Logger.make(LoggerType.fromPino(logger))
167
+ Layer.mergeAll(
168
+ EffectLogger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger),
169
+ Layer.succeed(Pino, pinoCtx)
170
+ )
101
171
  );
102
- };
103
- static replaceChild = (...params) => (e) => Effect.gen(function* () {
104
- const logger = yield* _Logger.get();
105
- if (logger == null) return yield* e;
106
- const child = logger.child(...params);
107
- return yield* Effect.provideService(e, _Logger, _Logger.make(child));
108
172
  });
109
- // --
110
- static info = Effect.fn(function* (...params) {
111
- const logger = yield* _Logger.get();
112
- if (logger == null) return;
113
- logger.info(...params);
173
+ Logger2.replaceChild = (...params) => (e) => Effect.gen(function* () {
174
+ const oldPinoCtx = yield* Pino;
175
+ const pino2 = oldPinoCtx.pino.child(...params);
176
+ const pinoCtx = PinoCtx.create(pino2);
177
+ return yield* Effect.provide(
178
+ Effect.provide(
179
+ e,
180
+ EffectLogger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger)
181
+ ),
182
+ Layer.succeed(Pino, pinoCtx)
183
+ );
114
184
  });
115
- static debug = Effect.fn(function* (...params) {
116
- const logger = yield* _Logger.get();
117
- if (logger == null) return;
118
- logger.debug(...params);
185
+ Logger2.info = (...params) => Effect.gen(function* () {
186
+ const { message, attributes } = extractParams(...params);
187
+ yield* Effect.logInfo(message).pipe(
188
+ attributes ? Effect.annotateLogs(attributes) : (e) => e
189
+ );
119
190
  });
120
- static warn = Effect.fn(function* (...params) {
121
- const logger = yield* _Logger.get();
122
- if (logger == null) return;
123
- logger.warn(...params);
191
+ Logger2.debug = (...params) => Effect.gen(function* () {
192
+ const { message, attributes } = extractParams(...params);
193
+ yield* Effect.logDebug(message).pipe(
194
+ attributes ? Effect.annotateLogs(attributes) : (e) => e
195
+ );
124
196
  });
125
- static error = Effect.fn(function* (...params) {
126
- const logger = yield* _Logger.get();
127
- if (logger == null) return;
128
- logger.error(...params);
197
+ Logger2.warn = (...params) => Effect.gen(function* () {
198
+ const { message, attributes } = extractParams(...params);
199
+ yield* Effect.logWarning(message).pipe(
200
+ attributes ? Effect.annotateLogs(attributes) : (e) => e
201
+ );
129
202
  });
130
- static flush = Effect.fn(function* (...params) {
131
- const logger = yield* _Logger.get();
132
- if (logger == null) return;
133
- logger.flush(...params);
203
+ Logger2.error = (...params) => Effect.gen(function* () {
204
+ const { message, attributes } = extractParams(...params);
205
+ yield* Effect.logError(message).pipe(
206
+ attributes ? Effect.annotateLogs(attributes) : (e) => e
207
+ );
134
208
  });
135
- };
209
+ Logger2.flush = (..._params) => Effect.void;
210
+ })(Logger || (Logger = {}));
136
211
  export {
137
212
  Logger
138
213
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/logger.ts"],"sourcesContent":["import { Config, Effect, Layer, Option } from 'effect';\nimport pino from 'pino';\n\n// Base logger\n\nnamespace LoggerType {\n\texport function fromPino(x: pino.Logger<never, boolean>) {\n\t\treturn {\n\t\t\tinfo: x.info.bind(x),\n\t\t\terror: x.error.bind(x),\n\t\t\twarn: x.warn.bind(x),\n\t\t\tdebug: x.debug.bind(x),\n\t\t\tchild: (...params: Parameters<typeof x.child>) => {\n\t\t\t\treturn fromPino(\n\t\t\t\t\tx.child(...params) as unknown as pino.Logger<never, boolean>,\n\t\t\t\t);\n\t\t\t},\n\t\t\tflush: x.flush.bind(x),\n\t\t\t_pino: x,\n\t\t};\n\t}\n\n\texport type CreateParams = {\n\t\tlevel?: pino.Level;\n\t\tstream?: pino.DestinationStream;\n\t};\n\n\texport function create(params?: CreateParams) {\n\t\tconst logger = pino(\n\t\t\t{\n\t\t\t\tlevel: params?.level ?? 'info',\n\t\t\t\tserializers: {\n\t\t\t\t\terror: pino.stdSerializers.errWithCause,\n\t\t\t\t\terr: pino.stdSerializers.errWithCause,\n\t\t\t\t},\n\t\t\t\tformatters: {\n\t\t\t\t\tlevel: (label) => {\n\t\t\t\t\t\treturn { level: label };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams?.stream,\n\t\t);\n\t\treturn fromPino(logger);\n\t}\n\n\texport function is(x: object): x is LoggerType {\n\t\treturn '_pino' in x;\n\t}\n}\ntype LoggerType = ReturnType<typeof LoggerType.create>;\n\n// Effect service\nconst createInstance = Effect.fn(function* (params?: LoggerType.CreateParams) {\n\tconst isDev = Option.getOrNull(\n\t\tyield* Config.boolean('DEV').pipe(Config.option),\n\t);\n\tconst logFile = Option.getOrNull(\n\t\tyield* Config.boolean('LOGGER_LOGFILE').pipe(Config.option),\n\t);\n\n\treturn LoggerType.create({\n\t\t...params,\n\t\t...(isDev && {\n\t\t\tstream: logFile\n\t\t\t\t? pino.transport({\n\t\t\t\t\t\ttarget: 'pino/file',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tdestination: './logs/server.log',\n\t\t\t\t\t\t\tmkdir: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t: pino.transport({\n\t\t\t\t\t\ttarget: 'pino-pretty',\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tignore: 'pid,hostname',\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t}),\n\t});\n});\n\nconst tag = 'ff-serv/logger' as const;\nexport class Logger extends Effect.Service<Logger>()(tag, {\n\teffect: createInstance(),\n}) {\n\tstatic create(params?: LoggerType.CreateParams) {\n\t\treturn Logger.make(LoggerType.create(params));\n\t}\n\n\tstatic layer = (params?: Parameters<typeof createInstance>[0]) =>\n\t\tLayer.effect(\n\t\t\tLogger,\n\t\t\tEffect.gen(function* () {\n\t\t\t\treturn Logger.make(yield* createInstance(params));\n\t\t\t}),\n\t\t);\n\n\t//\n\n\tstatic get = Effect.fn(function* () {\n\t\tconst logger = yield* Effect.serviceOption(Logger);\n\t\tif (Option.isNone(logger)) return undefined;\n\t\treturn logger.value;\n\t});\n\n\tstatic replace =\n\t\t(logger: Logger | LoggerType | pino.Logger | undefined) =>\n\t\t<A, E, R>(e: Effect.Effect<A, E, R>) => {\n\t\t\tif (logger == null) return e;\n\t\t\tif (logger instanceof Logger)\n\t\t\t\treturn Effect.provideService(e, Logger, logger);\n\n\t\t\tif (LoggerType.is(logger)) {\n\t\t\t\treturn Effect.provideService(e, Logger, Logger.make(logger));\n\t\t\t}\n\n\t\t\treturn Effect.provideService(\n\t\t\t\te,\n\t\t\t\tLogger,\n\t\t\t\tLogger.make(LoggerType.fromPino(logger)),\n\t\t\t);\n\t\t};\n\n\tstatic replaceChild =\n\t\t(...params: Parameters<LoggerType['child']>) =>\n\t\t<A, E, R>(e: Effect.Effect<A, E, R>) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst logger = yield* Logger.get();\n\t\t\t\tif (logger == null) return yield* e;\n\n\t\t\t\tconst child = logger.child(...params);\n\t\t\t\treturn yield* Effect.provideService(e, Logger, Logger.make(child));\n\t\t\t});\n\n\t// --\n\n\tstatic info = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['info']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.info(...params);\n\t});\n\n\tstatic debug = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['debug']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.debug(...params);\n\t});\n\n\tstatic warn = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['warn']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.warn(...params);\n\t});\n\n\tstatic error = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['error']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.error(...params);\n\t});\n\n\tstatic flush = Effect.fn(function* (\n\t\t...params: Parameters<LoggerType['flush']>\n\t) {\n\t\tconst logger = yield* Logger.get();\n\t\tif (logger == null) return;\n\t\tlogger.flush(...params);\n\t});\n}\n"],"mappings":"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","names":["LoggerType"]}
1
+ {"version":3,"sources":["../src/logger.ts"],"sourcesContent":["import {\n\tConfig,\n\tContext,\n\tEffect,\n\tLogger as EffectLogger,\n\tHashMap,\n\tLayer,\n\tLogLevel,\n\tManagedRuntime,\n\tOption,\n} from 'effect';\nimport pino from 'pino';\n\n// Pino Instance\n\nnamespace LoggerType {\n\texport function fromPino(x: pino.Logger<never, boolean>) {\n\t\treturn {\n\t\t\tinfo: x.info.bind(x),\n\t\t\terror: x.error.bind(x),\n\t\t\twarn: x.warn.bind(x),\n\t\t\tdebug: x.debug.bind(x),\n\t\t\tchild: (...params: Parameters<typeof x.child>) => {\n\t\t\t\treturn fromPino(\n\t\t\t\t\tx.child(...params) as unknown as pino.Logger<never, boolean>,\n\t\t\t\t);\n\t\t\t},\n\t\t\tflush: x.flush.bind(x),\n\t\t\t_pino: x,\n\t\t};\n\t}\n\n\texport type CreateParams = {\n\t\tstream?: pino.DestinationStream;\n\t};\n\n\texport function create(params?: CreateParams) {\n\t\tconst logger = pino(\n\t\t\t{\n\t\t\t\tlevel: 'trace', // Level is managed by Effect, so we set the lowest here\n\t\t\t\tserializers: {\n\t\t\t\t\terror: pino.stdSerializers.errWithCause,\n\t\t\t\t\terr: pino.stdSerializers.errWithCause,\n\t\t\t\t},\n\t\t\t\tformatters: {\n\t\t\t\t\tlevel: (label) => {\n\t\t\t\t\t\treturn { level: label };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams?.stream,\n\t\t);\n\t\treturn fromPino(logger);\n\t}\n\n\texport type Type = ReturnType<typeof LoggerType.create>;\n\n\texport function is(x: object): x is Type {\n\t\treturn '_pino' in x;\n\t}\n}\ntype LoggerType = LoggerType.Type;\n\n// The Gist\n\nconst createInstance = (params?: LoggerType.CreateParams) =>\n\tEffect.gen(function* () {\n\t\tconst isDev = Option.getOrNull(\n\t\t\tyield* Config.boolean('DEV').pipe(Config.option),\n\t\t);\n\t\tconst logFile = Option.getOrNull(\n\t\t\tyield* Config.boolean('LOGGER_LOGFILE').pipe(Config.option),\n\t\t);\n\n\t\treturn LoggerType.create({\n\t\t\t...params,\n\t\t\t...(isDev && {\n\t\t\t\tstream: logFile\n\t\t\t\t\t? pino.transport({\n\t\t\t\t\t\t\ttarget: 'pino/file',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tdestination: './logs/server.log',\n\t\t\t\t\t\t\t\tmkdir: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t: pino.transport({\n\t\t\t\t\t\t\ttarget: 'pino-pretty',\n\t\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t\tignore: 'pid,hostname',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t}),\n\t\t});\n\t});\n\n// Pino Context and Effect Logger integration\n\ntype LogParams = [obj: unknown, msg?: string];\nfunction extractParams(...[obj, msg]: LogParams) {\n\tif (typeof obj === 'string') {\n\t\treturn { message: obj };\n\t}\n\treturn { message: msg, attributes: obj as Record<string, any> };\n}\n\n/** A simple helper for calling pino log functions */\nfunction callPino(\n\t{\n\t\tannotations,\n\t\tmessage,\n\t}: Pick<EffectLogger.Logger.Options<unknown>, 'annotations' | 'message'>,\n\tcall: (...params: [obj: unknown, msg?: string]) => void,\n) {\n\tconst entries = HashMap.toEntries(annotations);\n\tif (entries.length > 0) {\n\t\treturn call(Object.fromEntries(entries), String(message));\n\t}\n\n\treturn call(String(message));\n}\n\nnamespace PinoCtx {\n\tconst tag = 'ff-serv/Pino';\n\texport type Type = ReturnType<typeof create>;\n\n\texport function is(obj: unknown): obj is Type {\n\t\treturn (\n\t\t\ttypeof obj === 'object' &&\n\t\t\tobj != null &&\n\t\t\t'_tag' in obj &&\n\t\t\tobj._tag === tag\n\t\t);\n\t}\n\n\texport function create(pino: LoggerType) {\n\t\treturn {\n\t\t\t_tag: tag,\n\t\t\tpino,\n\t\t\teffectLogger: EffectLogger.make(({ logLevel, ...input }) => {\n\t\t\t\tswitch (logLevel) {\n\t\t\t\t\tcase LogLevel.Info:\n\t\t\t\t\t\treturn callPino(input, pino.info);\n\t\t\t\t\tcase LogLevel.Debug:\n\t\t\t\t\t\treturn callPino(input, pino.debug);\n\t\t\t\t\tcase LogLevel.Warning:\n\t\t\t\t\t\treturn callPino(input, pino.warn);\n\t\t\t\t\tcase LogLevel.Error:\n\t\t\t\t\tcase LogLevel.Fatal:\n\t\t\t\t\t\treturn callPino(input, pino.error);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn callPino(input, pino.info);\n\t\t\t\t}\n\t\t\t}),\n\t\t};\n\t}\n}\ntype PinoCtx = PinoCtx.Type;\n\nclass Pino extends Context.Tag('ff-serv/Pino')<Pino, PinoCtx>() {}\n\n// Facade\n\nexport namespace Logger {\n\texport const layer = (opts?: Parameters<typeof createInstance>[0]) =>\n\t\tEffectLogger.replaceEffect(\n\t\t\tEffectLogger.defaultLogger,\n\t\t\tEffect.gen(function* () {\n\t\t\t\treturn (yield* Pino).effectLogger;\n\t\t\t}),\n\t\t).pipe(\n\t\t\tLayer.provideMerge(\n\t\t\t\tLayer.effect(\n\t\t\t\t\tPino,\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\treturn PinoCtx.create(yield* createInstance(opts));\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\texport const Default = layer();\n\n\t//\n\n\texport const sync = () =>\n\t\tEffect.gen(function* () {\n\t\t\tconst pino = yield* Pino;\n\t\t\tconst runtime = ManagedRuntime.make(\n\t\t\t\tEffectLogger.replace(EffectLogger.defaultLogger, pino.effectLogger),\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tinfo: (...params: Parameters<typeof Logger.info>) =>\n\t\t\t\t\tLogger.info(...params).pipe((e) => runtime.runSync(e)),\n\t\t\t\tdebug: (...params: Parameters<typeof Logger.debug>) =>\n\t\t\t\t\tLogger.debug(...params).pipe((e) => runtime.runSync(e)),\n\t\t\t\twarn: (...params: Parameters<typeof Logger.warn>) =>\n\t\t\t\t\tLogger.warn(...params).pipe((e) => runtime.runSync(e)),\n\t\t\t\terror: (...params: Parameters<typeof Logger.error>) =>\n\t\t\t\t\tLogger.error(...params).pipe((e) => runtime.runSync(e)),\n\t\t\t};\n\t\t});\n\n\t/** @deprecated — will be renamed to `sync` */\n\texport const get = () => Logger.sync();\n\n\texport const replace =\n\t\t(logger: LoggerType | pino.Logger) =>\n\t\t<A, E, R>(e: Effect.Effect<A, E, R>) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst oldPinoCtx = yield* Pino;\n\t\t\t\tconst pino = LoggerType.is(logger)\n\t\t\t\t\t? logger\n\t\t\t\t\t: LoggerType.fromPino(logger);\n\t\t\t\tconst pinoCtx = PinoCtx.create(pino);\n\n\t\t\t\treturn yield* Effect.provide(\n\t\t\t\t\te,\n\t\t\t\t\tLayer.mergeAll(\n\t\t\t\t\t\tEffectLogger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger),\n\t\t\t\t\t\tLayer.succeed(Pino, pinoCtx),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t});\n\n\texport const replaceChild =\n\t\t(...params: Parameters<LoggerType['child']>) =>\n\t\t<A, E, R>(e: Effect.Effect<A, E, R>) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst oldPinoCtx = yield* Pino;\n\t\t\t\tconst pino = oldPinoCtx.pino.child(...params);\n\t\t\t\tconst pinoCtx = PinoCtx.create(pino);\n\n\t\t\t\treturn yield* Effect.provide(\n\t\t\t\t\tEffect.provide(\n\t\t\t\t\t\te,\n\t\t\t\t\t\tEffectLogger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger),\n\t\t\t\t\t),\n\t\t\t\t\tLayer.succeed(Pino, pinoCtx),\n\t\t\t\t);\n\t\t\t});\n\n\t// --\n\n\texport const info = (...params: LogParams) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst { message, attributes } = extractParams(...params);\n\t\t\tyield* Effect.logInfo(message).pipe(\n\t\t\t\tattributes ? Effect.annotateLogs(attributes) : (e) => e,\n\t\t\t);\n\t\t});\n\n\texport const debug = (...params: LogParams) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst { message, attributes } = extractParams(...params);\n\t\t\tyield* Effect.logDebug(message).pipe(\n\t\t\t\tattributes ? Effect.annotateLogs(attributes) : (e) => e,\n\t\t\t);\n\t\t});\n\n\texport const warn = (...params: LogParams) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst { message, attributes } = extractParams(...params);\n\t\t\tyield* Effect.logWarning(message).pipe(\n\t\t\t\tattributes ? Effect.annotateLogs(attributes) : (e) => e,\n\t\t\t);\n\t\t});\n\n\texport const error = (...params: LogParams) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst { message, attributes } = extractParams(...params);\n\t\t\tyield* Effect.logError(message).pipe(\n\t\t\t\tattributes ? Effect.annotateLogs(attributes) : (e) => e,\n\t\t\t);\n\t\t});\n\n\t/** @deprecated */\n\texport const flush = (..._params: Parameters<LoggerType['flush']>) =>\n\t\tEffect.void;\n}\n"],"mappings":"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","names":["LoggerType","PinoCtx","pino","Logger"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ff-serv",
3
- "version": "0.0.2",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -25,7 +25,8 @@
25
25
  },
26
26
  "peerDependencies": {
27
27
  "effect": "^3.19.3",
28
- "pino": "^9"
28
+ "pino": "^9",
29
+ "@effect/opentelemetry": "^0.60.0"
29
30
  },
30
31
  "publishConfig": {
31
32
  "access": "public"
package/src/logger.ts CHANGED
@@ -1,7 +1,17 @@
1
- import { Config, Effect, Layer, Option } from 'effect';
1
+ import {
2
+ Config,
3
+ Context,
4
+ Effect,
5
+ Logger as EffectLogger,
6
+ HashMap,
7
+ Layer,
8
+ LogLevel,
9
+ ManagedRuntime,
10
+ Option,
11
+ } from 'effect';
2
12
  import pino from 'pino';
3
13
 
4
- // Base logger
14
+ // Pino Instance
5
15
 
6
16
  namespace LoggerType {
7
17
  export function fromPino(x: pino.Logger<never, boolean>) {
@@ -21,14 +31,13 @@ namespace LoggerType {
21
31
  }
22
32
 
23
33
  export type CreateParams = {
24
- level?: pino.Level;
25
34
  stream?: pino.DestinationStream;
26
35
  };
27
36
 
28
37
  export function create(params?: CreateParams) {
29
38
  const logger = pino(
30
39
  {
31
- level: params?.level ?? 'info',
40
+ level: 'trace', // Level is managed by Effect, so we set the lowest here
32
41
  serializers: {
33
42
  error: pino.stdSerializers.errWithCause,
34
43
  err: pino.stdSerializers.errWithCause,
@@ -44,134 +53,227 @@ namespace LoggerType {
44
53
  return fromPino(logger);
45
54
  }
46
55
 
47
- export function is(x: object): x is LoggerType {
56
+ export type Type = ReturnType<typeof LoggerType.create>;
57
+
58
+ export function is(x: object): x is Type {
48
59
  return '_pino' in x;
49
60
  }
50
61
  }
51
- type LoggerType = ReturnType<typeof LoggerType.create>;
52
-
53
- // Effect service
54
- const createInstance = Effect.fn(function* (params?: LoggerType.CreateParams) {
55
- const isDev = Option.getOrNull(
56
- yield* Config.boolean('DEV').pipe(Config.option),
57
- );
58
- const logFile = Option.getOrNull(
59
- yield* Config.boolean('LOGGER_LOGFILE').pipe(Config.option),
60
- );
61
-
62
- return LoggerType.create({
63
- ...params,
64
- ...(isDev && {
65
- stream: logFile
66
- ? pino.transport({
67
- target: 'pino/file',
68
- options: {
69
- destination: './logs/server.log',
70
- mkdir: true,
71
- },
72
- })
73
- : pino.transport({
74
- target: 'pino-pretty',
75
- options: {
76
- ignore: 'pid,hostname',
77
- },
78
- }),
79
- }),
62
+ type LoggerType = LoggerType.Type;
63
+
64
+ // The Gist
65
+
66
+ const createInstance = (params?: LoggerType.CreateParams) =>
67
+ Effect.gen(function* () {
68
+ const isDev = Option.getOrNull(
69
+ yield* Config.boolean('DEV').pipe(Config.option),
70
+ );
71
+ const logFile = Option.getOrNull(
72
+ yield* Config.boolean('LOGGER_LOGFILE').pipe(Config.option),
73
+ );
74
+
75
+ return LoggerType.create({
76
+ ...params,
77
+ ...(isDev && {
78
+ stream: logFile
79
+ ? pino.transport({
80
+ target: 'pino/file',
81
+ options: {
82
+ destination: './logs/server.log',
83
+ mkdir: true,
84
+ },
85
+ })
86
+ : pino.transport({
87
+ target: 'pino-pretty',
88
+ options: {
89
+ ignore: 'pid,hostname',
90
+ },
91
+ }),
92
+ }),
93
+ });
80
94
  });
81
- });
82
-
83
- const tag = 'ff-serv/logger' as const;
84
- export class Logger extends Effect.Service<Logger>()(tag, {
85
- effect: createInstance(),
86
- }) {
87
- static create(params?: LoggerType.CreateParams) {
88
- return Logger.make(LoggerType.create(params));
95
+
96
+ // Pino Context and Effect Logger integration
97
+
98
+ type LogParams = [obj: unknown, msg?: string];
99
+ function extractParams(...[obj, msg]: LogParams) {
100
+ if (typeof obj === 'string') {
101
+ return { message: obj };
102
+ }
103
+ return { message: msg, attributes: obj as Record<string, any> };
104
+ }
105
+
106
+ /** A simple helper for calling pino log functions */
107
+ function callPino(
108
+ {
109
+ annotations,
110
+ message,
111
+ }: Pick<EffectLogger.Logger.Options<unknown>, 'annotations' | 'message'>,
112
+ call: (...params: [obj: unknown, msg?: string]) => void,
113
+ ) {
114
+ const entries = HashMap.toEntries(annotations);
115
+ if (entries.length > 0) {
116
+ return call(Object.fromEntries(entries), String(message));
89
117
  }
90
118
 
91
- static layer = (params?: Parameters<typeof createInstance>[0]) =>
92
- Layer.effect(
93
- Logger,
119
+ return call(String(message));
120
+ }
121
+
122
+ namespace PinoCtx {
123
+ const tag = 'ff-serv/Pino';
124
+ export type Type = ReturnType<typeof create>;
125
+
126
+ export function is(obj: unknown): obj is Type {
127
+ return (
128
+ typeof obj === 'object' &&
129
+ obj != null &&
130
+ '_tag' in obj &&
131
+ obj._tag === tag
132
+ );
133
+ }
134
+
135
+ export function create(pino: LoggerType) {
136
+ return {
137
+ _tag: tag,
138
+ pino,
139
+ effectLogger: EffectLogger.make(({ logLevel, ...input }) => {
140
+ switch (logLevel) {
141
+ case LogLevel.Info:
142
+ return callPino(input, pino.info);
143
+ case LogLevel.Debug:
144
+ return callPino(input, pino.debug);
145
+ case LogLevel.Warning:
146
+ return callPino(input, pino.warn);
147
+ case LogLevel.Error:
148
+ case LogLevel.Fatal:
149
+ return callPino(input, pino.error);
150
+ default:
151
+ return callPino(input, pino.info);
152
+ }
153
+ }),
154
+ };
155
+ }
156
+ }
157
+ type PinoCtx = PinoCtx.Type;
158
+
159
+ class Pino extends Context.Tag('ff-serv/Pino')<Pino, PinoCtx>() {}
160
+
161
+ // Facade
162
+
163
+ export namespace Logger {
164
+ export const layer = (opts?: Parameters<typeof createInstance>[0]) =>
165
+ EffectLogger.replaceEffect(
166
+ EffectLogger.defaultLogger,
94
167
  Effect.gen(function* () {
95
- return Logger.make(yield* createInstance(params));
168
+ return (yield* Pino).effectLogger;
96
169
  }),
170
+ ).pipe(
171
+ Layer.provideMerge(
172
+ Layer.effect(
173
+ Pino,
174
+ Effect.gen(function* () {
175
+ return PinoCtx.create(yield* createInstance(opts));
176
+ }),
177
+ ),
178
+ ),
97
179
  );
98
180
 
99
- //
181
+ export const Default = layer();
100
182
 
101
- static get = Effect.fn(function* () {
102
- const logger = yield* Effect.serviceOption(Logger);
103
- if (Option.isNone(logger)) return undefined;
104
- return logger.value;
105
- });
183
+ //
106
184
 
107
- static replace =
108
- (logger: Logger | LoggerType | pino.Logger | undefined) =>
109
- <A, E, R>(e: Effect.Effect<A, E, R>) => {
110
- if (logger == null) return e;
111
- if (logger instanceof Logger)
112
- return Effect.provideService(e, Logger, logger);
113
-
114
- if (LoggerType.is(logger)) {
115
- return Effect.provideService(e, Logger, Logger.make(logger));
116
- }
117
-
118
- return Effect.provideService(
119
- e,
120
- Logger,
121
- Logger.make(LoggerType.fromPino(logger)),
185
+ export const sync = () =>
186
+ Effect.gen(function* () {
187
+ const pino = yield* Pino;
188
+ const runtime = ManagedRuntime.make(
189
+ EffectLogger.replace(EffectLogger.defaultLogger, pino.effectLogger),
122
190
  );
123
- };
191
+ return {
192
+ info: (...params: Parameters<typeof Logger.info>) =>
193
+ Logger.info(...params).pipe((e) => runtime.runSync(e)),
194
+ debug: (...params: Parameters<typeof Logger.debug>) =>
195
+ Logger.debug(...params).pipe((e) => runtime.runSync(e)),
196
+ warn: (...params: Parameters<typeof Logger.warn>) =>
197
+ Logger.warn(...params).pipe((e) => runtime.runSync(e)),
198
+ error: (...params: Parameters<typeof Logger.error>) =>
199
+ Logger.error(...params).pipe((e) => runtime.runSync(e)),
200
+ };
201
+ });
202
+
203
+ /** @deprecated — will be renamed to `sync` */
204
+ export const get = () => Logger.sync();
205
+
206
+ export const replace =
207
+ (logger: LoggerType | pino.Logger) =>
208
+ <A, E, R>(e: Effect.Effect<A, E, R>) =>
209
+ Effect.gen(function* () {
210
+ const oldPinoCtx = yield* Pino;
211
+ const pino = LoggerType.is(logger)
212
+ ? logger
213
+ : LoggerType.fromPino(logger);
214
+ const pinoCtx = PinoCtx.create(pino);
215
+
216
+ return yield* Effect.provide(
217
+ e,
218
+ Layer.mergeAll(
219
+ EffectLogger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger),
220
+ Layer.succeed(Pino, pinoCtx),
221
+ ),
222
+ );
223
+ });
124
224
 
125
- static replaceChild =
225
+ export const replaceChild =
126
226
  (...params: Parameters<LoggerType['child']>) =>
127
227
  <A, E, R>(e: Effect.Effect<A, E, R>) =>
128
228
  Effect.gen(function* () {
129
- const logger = yield* Logger.get();
130
- if (logger == null) return yield* e;
229
+ const oldPinoCtx = yield* Pino;
230
+ const pino = oldPinoCtx.pino.child(...params);
231
+ const pinoCtx = PinoCtx.create(pino);
131
232
 
132
- const child = logger.child(...params);
133
- return yield* Effect.provideService(e, Logger, Logger.make(child));
233
+ return yield* Effect.provide(
234
+ Effect.provide(
235
+ e,
236
+ EffectLogger.replace(oldPinoCtx.effectLogger, pinoCtx.effectLogger),
237
+ ),
238
+ Layer.succeed(Pino, pinoCtx),
239
+ );
134
240
  });
135
241
 
136
242
  // --
137
243
 
138
- static info = Effect.fn(function* (
139
- ...params: Parameters<LoggerType['info']>
140
- ) {
141
- const logger = yield* Logger.get();
142
- if (logger == null) return;
143
- logger.info(...params);
144
- });
244
+ export const info = (...params: LogParams) =>
245
+ Effect.gen(function* () {
246
+ const { message, attributes } = extractParams(...params);
247
+ yield* Effect.logInfo(message).pipe(
248
+ attributes ? Effect.annotateLogs(attributes) : (e) => e,
249
+ );
250
+ });
145
251
 
146
- static debug = Effect.fn(function* (
147
- ...params: Parameters<LoggerType['debug']>
148
- ) {
149
- const logger = yield* Logger.get();
150
- if (logger == null) return;
151
- logger.debug(...params);
152
- });
252
+ export const debug = (...params: LogParams) =>
253
+ Effect.gen(function* () {
254
+ const { message, attributes } = extractParams(...params);
255
+ yield* Effect.logDebug(message).pipe(
256
+ attributes ? Effect.annotateLogs(attributes) : (e) => e,
257
+ );
258
+ });
153
259
 
154
- static warn = Effect.fn(function* (
155
- ...params: Parameters<LoggerType['warn']>
156
- ) {
157
- const logger = yield* Logger.get();
158
- if (logger == null) return;
159
- logger.warn(...params);
160
- });
260
+ export const warn = (...params: LogParams) =>
261
+ Effect.gen(function* () {
262
+ const { message, attributes } = extractParams(...params);
263
+ yield* Effect.logWarning(message).pipe(
264
+ attributes ? Effect.annotateLogs(attributes) : (e) => e,
265
+ );
266
+ });
161
267
 
162
- static error = Effect.fn(function* (
163
- ...params: Parameters<LoggerType['error']>
164
- ) {
165
- const logger = yield* Logger.get();
166
- if (logger == null) return;
167
- logger.error(...params);
168
- });
268
+ export const error = (...params: LogParams) =>
269
+ Effect.gen(function* () {
270
+ const { message, attributes } = extractParams(...params);
271
+ yield* Effect.logError(message).pipe(
272
+ attributes ? Effect.annotateLogs(attributes) : (e) => e,
273
+ );
274
+ });
169
275
 
170
- static flush = Effect.fn(function* (
171
- ...params: Parameters<LoggerType['flush']>
172
- ) {
173
- const logger = yield* Logger.get();
174
- if (logger == null) return;
175
- logger.flush(...params);
176
- });
276
+ /** @deprecated */
277
+ export const flush = (..._params: Parameters<LoggerType['flush']>) =>
278
+ Effect.void;
177
279
  }