Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add functionality to customize log layout and introduce JSON logger #5732

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
"lodash.groupby": "^4.6.0",
"lodash.sortby": "^4.7.0",
"log4js": "^6.0.0",
"log4js-json-layout": "^2.2.3",
"make-fetch-happen": "^11.0.0",
"memoizee": "^0.4.15",
"mime": "^3.0.0",
Expand Down
4 changes: 3 additions & 1 deletion src/lib/create-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,9 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {

const logLevel =
options.logLevel || LogLevel[process.env.LOG_LEVEL] || LogLevel.error;
const getLogger = options.getLogger || getDefaultLogProvider(logLevel);
const logLayout = options.logLayout || process.env.LOG_LAYOUT || 'basic';
const getLogger =
options.getLogger || getDefaultLogProvider(logLevel, logLayout);
validateLogProvider(getLogger);

const server: IServerOption = mergeAll([
Expand Down
11 changes: 9 additions & 2 deletions src/lib/logger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { configure, getLogger } from 'log4js';
import { configure, getLogger, addLayout, Layout } from 'log4js';
import jsonLayout from 'log4js-json-layout';

export type LogProvider = (category?: string) => Logger;

Expand All @@ -20,10 +21,16 @@ export interface Logger {

export function getDefaultLogProvider(
logLevel: LogLevel = LogLevel.error,
logLayout: string | Layout = 'basic',
): LogProvider {
addLayout('json', jsonLayout);

const layout =
typeof logLayout === 'string' ? { type: logLayout } : logLayout;

configure({
appenders: {
console: { type: 'console' },
console: { type: 'console', layout: layout },
},
categories: {
default: { appenders: ['console'], level: logLevel },
Expand Down
2 changes: 2 additions & 0 deletions src/lib/types/option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ILegacyApiTokenCreate } from './models/api-token';
import { IFlagResolver, IExperimentalOptions, IFlags } from './experimental';
import SMTPTransport from 'nodemailer/lib/smtp-transport';
import { IUnleashServices } from './services';
import { Layout } from 'log4js';

export interface ISSLOption {
rejectUnauthorized: boolean;
Expand Down Expand Up @@ -109,6 +110,7 @@ export interface IUnleashOptions {
session?: Partial<ISessionOption>;
getLogger?: LogProvider;
logLevel?: LogLevel;
logLayout?: string | Layout;
Copy link
Member

@ivarconr ivarconr Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change ends up exposing which internal logging framework Unleash uses, which should be an implementation detail, and not exposed to the end users. By exposing it we cannot change it without doing a major release.

server?: Partial<IServerOption>;
versionCheck?: Partial<IVersionOption>;
telemetry?: boolean;
Expand Down
1 change: 1 addition & 0 deletions website/docs/using-unleash/deploy/configuring-unleash.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ unleash.start(unleashOptions);
- ~~eventHook~~ (`function(event, data)`) - (_deprecated in Unleash 4.3_ in favor of the [Webhook integration](/reference/integrations/webhook.md). **Removed in Unleash 5**) If provided, this function will be invoked whenever a feature is mutated. The possible values for `event` are `'feature-created'`, `'feature-archived'` and `'feature-revived'`. The `data` argument contains information about the mutation. Its fields are `type` (string) - the event type (same as `event`); `createdBy` (string) - the user who performed the mutation; `data` - the contents of the change. The contents in `data` differs based on the event type; For `'feature-archived'` and `'feature-revived'`, the only field will be `name` - the name of the feature. For `'feature-created'` the data follows a schema defined in the code [here](https://github.com/Unleash/unleash/blob/7b7f0b84e8cddd5880dcf29c231672113224b9a7/src/lib/schema/feature-schema.ts#L77). See an [api here](/reference/api/legacy/unleash/admin/events).
- **getLogger** (function) - Used to register a [custom log provider](#how-do-i-configure-the-log-output).
- **logLevel** (`debug` | `info` | `warn` | `error` | `fatal`) - The lowest level to log at, also configurable using environment variable `LOG_LEVEL`.
- **logLayout** - A [log layout](https://log4js-node.github.io/log4js-node/layouts.html) to apply to log4js. May be the name of a layout or a complete layout object if further configuration is needed. The `LOG_LAYOUT` environment may also be used if only the layout name is required. Besides the bundled layouts provided by log4js, the [`json`](https://github.com/id0Sch/log4js-json-layout) layout is supported for structured logs.
- **enableRequestLogger** (boolean) - use this to enable logging for requested urls and response codes (default: false).
- **preHook** (function) - this is a hook if you need to provide any middlewares to express before `unleash` adds any. Express app instance is injected as first argument.
- **preRouterHook** (function) - use this to register custom express middlewares before the `unleash` specific routers are added.
Expand Down
15 changes: 14 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,11 @@ colors@1.0.x:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
integrity sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==

colors@^1.1.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==

combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
Expand Down Expand Up @@ -4669,7 +4674,7 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==

lodash@^4.17.21:
lodash@^4.17.21, lodash@^4.17.4:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
Expand All @@ -4689,6 +4694,14 @@ log-update@^4.0.0:
slice-ansi "^4.0.0"
wrap-ansi "^6.2.0"

log4js-json-layout@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/log4js-json-layout/-/log4js-json-layout-2.2.3.tgz#a9e95aff1f79e3e4bdd762a8a45fc0b5c81276cc"
integrity sha512-sKebdMKxF7ehqT5x760xGAI8rujDPu5dLf0p/s5e48GQYvRCkI1ycFxb6b7R8y7IZoBaXg/piL6LsMaE6Rg4gQ==
dependencies:
colors "^1.1.2"
lodash "^4.17.4"

log4js@^6.0.0:
version "6.9.1"
resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.9.1.tgz#aba5a3ff4e7872ae34f8b4c533706753709e38b6"
Expand Down