Skip to content

Commit

Permalink
Check Changelog in README, v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
eajr committed Mar 28, 2024
1 parent e9c91b2 commit 836c707
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 74 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ bun add @eajr/elylog

```ts
import { Elysia } from "elysia";
import { elylog } from "@eajr/elylog";
import { elylog, LogType } from "@eajr/elylog";

const app = new Elysia()
.use(elylog())
.get("/", (ctx) => {
ctx.log.error("There was an error");
ctx.log.info("Here's some info");
ctx.log.warn("Beware!");
ctx.log(LogType.INFO, { message: "There was an error" });
ctx.log(LogType.ERROR, { message: "Here's some info" });
ctx.log(LogType.WARNING, { message: "Beware!" });
return "Hello World";
})
.listen(8080);
Expand All @@ -31,7 +31,7 @@ console.log(`Listening on http://${app.server!.hostname}:${app.server!.port}`);

```json
{"timestamp":"2024-03-19T20:53:27.453Z","type":"SYS","uuid":"1967b8c9-588b-4d43-933d-1658c453efc6","method":"GET","path":"/info"}
{"timestamp":"2024-03-19T20:53:27.453Z","type":"INFO","uuid":"1967b8c9-588b-4d43-933d-1658c453efc6","message":"info test"}
{"timestamp":"2024-03-19T20:53:27.453Z","type":"INFO","uuid":"1967b8c9-588b-4d43-933d-1658c453efc6","data": { "message":"info test"}}
{"timestamp":"2024-03-19T20:53:27.454Z","type":"META","uuid":"1967b8c9-588b-4d43-933d-1658c453efc6","duration":6}
```

Expand Down Expand Up @@ -67,6 +67,13 @@ export interface Options {

For some reason the [Elysia-Swagger](https://github.com/elysiajs/elysia-swagger) plugin breaks if you instantiate elylog before the swagger plugin. It also breaks for other logging plugins, so make sure to `.use(elylog())` after you use the swagger plugin.

## Changelog

#### v1.0.0

- Changed text logging (via context logger) to object logging
- Added multi-file elysia example api in `/examples/multifile`

## License

[MIT](LICENSE.md)
Empty file added examples/custom/.gitkeep
Empty file.
13 changes: 13 additions & 0 deletions examples/multifile/handlers/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type exampleGetByIdResponse } from "../models/example";
import { LogType, type ILoggerFn } from "../../../src/types";

export const exampleGetById = async (id: number, log: ILoggerFn) => {
log(LogType.INFO, { id: id });

let res: exampleGetByIdResponse = {
name: "This is an example name",
address: "201 Wannakee Rd",
};

return res;
};
20 changes: 20 additions & 0 deletions examples/multifile/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Elysia } from "elysia";

// plugins
import { elylog } from "../../src/index";

// routes
import { ExampleRoutes } from "./routes/example";

const app = new Elysia()
// plugins
.use(elylog())

// routes
.use(ExampleRoutes)

.listen(3000);

console.log(
`🦊 Example API is running at ${app.server?.hostname}:${app.server?.port}`
);
16 changes: 16 additions & 0 deletions examples/multifile/models/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { t, Static } from "elysia";

const exampleGetByIdResponse = t.Object({
name: t.String({
description: "Example name",
default: "Test Name",
}),
address: t.String({
description: "Example street address",
default: "123 Main St",
}),
});

export type exampleGetByIdResponse = Static<typeof exampleGetByIdResponse>;

export { exampleGetByIdResponse };
18 changes: 18 additions & 0 deletions examples/multifile/routes/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Elysia, t } from "elysia";
import { exampleGetById } from "../handlers/example";
import { exampleGetByIdResponse } from "../models/example";
import { elylog } from "../../../src/index";

export const ExampleRoutes = new Elysia()
.use(elylog())
.get("/:id", ({ params: { id }, log }) => exampleGetById(id, log), {
params: t.Object({
id: t.Numeric(),
}),
response: exampleGetByIdResponse,
detail: {
summary: "Get Example by ID",
description: "An example GET request",
tags: ["ExampleTag"],
},
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eajr/elylog",
"version": "0.1.3",
"version": "1.0.0",
"description": "A plugin for Elysia.js that handles basic stdout logging",
"module": "src/index.ts",
"type": "module",
Expand Down
87 changes: 19 additions & 68 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,15 @@
import { Elysia, type Context } from "elysia";
import { randomUUID } from "node:crypto";

export enum LogType {
SYSTEM = "SYS",
METADATA = "META",
INFO = "INFO",
WARNING = "WARN",
ERROR = "ERR",
}

type LogBase = {
timestamp: Date;
type: LogType;
uuid: string;
};

export type LogRequest = LogBase & {
method: string;
path: string;
};

export type LogMessage = LogBase & {
message: string;
};

export type LogMetaData = LogBase & {
duration: number;
};

export interface Options {
// Elylog generates a request ID (uuidv4) by default on request.
// Set this to a header to use request id's generated by client
// Default: null
headerForRequestId?: string;

// Log all requests (SYS log type): true (default)
logRequests?: boolean;

// Log metadata at the end of life cycle (META log type): true (default)
// Metadata:
// - Duration (in ms)
logMetaData?: boolean;

// Custom print function for request logs (SYS log type): JSON (default)
requestPrintFn?(log: LogRequest): void;

// Custom print function for log messages (INFO|WARNING|ERROR): JSON (default)
logPrintFn?(log: LogMessage): void;

// Custom print function for metadata messages (META): JSON (default)
metadataPrintFn?(log: LogMetaData): void;
}

const defaultOptions: Options = {
import {
LogType,
type LogMessage,
type LogMetaData,
type LogRequest,
type IOptions,
type ILoggerFn,
} from "./types";

const defaultOptions: IOptions = {
headerForRequestId: undefined,
logRequests: true,
logMetaData: true,
Expand All @@ -75,35 +32,29 @@ const defaultOptions: Options = {
};

// Main plugin
export const elylog = (options?: Options) => {
export const elylog = (options?: IOptions) => {
if (options === undefined) options = defaultOptions;
else options = { ...defaultOptions, ...options };

return new Elysia({
name: "@eajr/elylog",
})
.derive((ctx) => {
const raw = (type: LogType, message: string) => {
const raw = (type: LogType, data: object) => {
let log: LogMessage = {
timestamp: new Date(),
type: type,
uuid: (ctx.store as any).elylogRequestId,
message: message,
data: data,
};
options?.logPrintFn?.(log);
};
const logger: ILoggerFn = (type: LogType, data: object) => {
raw(type, data);
};

return {
log: {
info: (message: string) => {
raw(LogType.INFO, message);
},
warn: (message: string) => {
raw(LogType.WARNING, message);
},
error: (message: string) => {
raw(LogType.ERROR, message);
},
},
log: logger,
};
})
.onRequest((ctx) => {
Expand Down Expand Up @@ -136,7 +87,7 @@ export const elylog = (options?: Options) => {
.onError((ctx) => {});
};

const onResponse = (options: Options) => {
const onResponse = (options: IOptions) => {
return (ctx: Context) => {
if (options?.logMetaData) {
const reqStart = (ctx.store as any).elylogRequestStart;
Expand Down
58 changes: 58 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export enum LogType {
SYSTEM = "SYS",
METADATA = "META",
INFO = "INFO",
WARNING = "WARN",
ERROR = "ERR",
}

export type LogBase = {
timestamp: Date;
type: LogType;
uuid: string;
};

export type LogRequest = LogBase & {
method: string;
path: string;
};

export type LogMessage = LogBase & {
data: object;
};

export type LogMetaData = LogBase & {
duration: number;
};

export interface ILoggerFn {
(type: LogType, data: object): void;
}

export interface ILogger {
log: ILoggerFn;
}

export interface IOptions {
// Elylog generates a request ID (uuidv4) by default on request.
// Set this to a header to use request id's generated by client
// Default: null
headerForRequestId?: string;

// Log all requests (SYS log type): true (default)
logRequests?: boolean;

// Log metadata at the end of life cycle (META log type): true (default)
// Metadata:
// - Duration (in ms)
logMetaData?: boolean;

// Custom print function for request logs (SYS log type): JSON (default)
requestPrintFn?(log: LogRequest): void;

// Custom print function for log messages (INFO|WARNING|ERROR): JSON (default)
logPrintFn?(log: LogMessage): void;

// Custom print function for metadata messages (META): JSON (default)
metadataPrintFn?(log: LogMetaData): void;
}

0 comments on commit 836c707

Please sign in to comment.