Skip to content

Commit

Permalink
Renderer file logging transport (#6795)
Browse files Browse the repository at this point in the history
* Renderer file logging transport

Add file logging to renderer, writing separate log files for renderer main frame and each cluster frame.

Related to lensapp/support-lens-extension#118

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>

* Switch renderer file log level to info

There is too much noise on debug level from api responses etc

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>

* Unmount on pagehide instead of beforeunload

It seems cluster onbeforeunload is not triggered when iframe is removed from dom by the parent (when disconnecting a cluster).

While on root/main frame the beforeunload event does work, it seems to be adviced to use pagehide instead.

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>

* Close log files on unmount

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>

* Improve file handle closing in different situations

This should cover reloading main and cluster frames and closing cluster frame throught disconnecting cluster. No file handles should be left open now.

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>

* Fix renderer log rotation

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>

* Switch back to beforeunload in root frame

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>

* Remove capturing phase event usage

Does not seem to be needed for log files to be successfully closed and caused integration tests to fail.

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>

---------

Signed-off-by: Sami Tiilikainen <97873007+samitiilikainen@users.noreply.github.com>
  • Loading branch information
samitiilikainen committed Feb 8, 2023
1 parent c12561f commit ac2d0e4
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 14 deletions.
11 changes: 2 additions & 9 deletions packages/core/src/common/logger.injectable.ts
Expand Up @@ -3,20 +3,13 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { createLogger, format } from "winston";
import type { Logger } from "./logger";
import { loggerTransportInjectionToken } from "./logger/transports";
import winstonLoggerInjectable from "./winston-logger.injectable";

const loggerInjectable = getInjectable({
id: "logger",
instantiate: (di): Logger => {
const baseLogger = createLogger({
format: format.combine(
format.splat(),
format.simple(),
),
transports: di.injectMany(loggerTransportInjectionToken),
});
const baseLogger = di.inject(winstonLoggerInjectable);

return {
debug: (message, ...data) => baseLogger.debug(message, ...data),
Expand Down
20 changes: 20 additions & 0 deletions packages/core/src/common/winston-logger.injectable.ts
@@ -0,0 +1,20 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { createLogger, format } from "winston";
import { loggerTransportInjectionToken } from "./logger/transports";

const winstonLoggerInjectable = getInjectable({
id: "winston-logger",
instantiate: (di) => createLogger({
format: format.combine(
format.splat(),
format.simple(),
),
transports: di.injectMany(loggerTransportInjectionToken),
}),
});

export default winstonLoggerInjectable;
4 changes: 3 additions & 1 deletion packages/core/src/renderer/bootstrap.tsx
Expand Up @@ -54,7 +54,9 @@ export async function bootstrap(di: DiContainer) {
}

try {
await initializeApp(() => unmountComponentAtNode(rootElem));
await initializeApp(() => {
unmountComponentAtNode(rootElem);
});
} catch (error) {
console.error(`[BOOTSTRAP]: view initialization error: ${error}`, {
origin: location.href,
Expand Down
Expand Up @@ -12,6 +12,7 @@ import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.
import loadExtensionsInjectable from "../../load-extensions.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
import showErrorNotificationInjectable from "../../../components/notifications/show-error-notification.injectable";
import closeRendererLogFileInjectable from "../../../logger/close-renderer-log-file.injectable";

const initClusterFrameInjectable = getInjectable({
id: "init-cluster-frame",
Expand All @@ -29,6 +30,7 @@ const initClusterFrameInjectable = getInjectable({
emitAppEvent: di.inject(emitAppEventInjectable),
logger: di.inject(loggerInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
closeFileLogging: di.inject(closeRendererLogFileInjectable),
});
},
});
Expand Down
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { once } from "lodash";
import type { Cluster } from "../../../../common/cluster/cluster";
import type { CatalogEntityRegistry } from "../../../api/catalog/entity/registry";
import type { ShowNotification } from "../../../components/notifications";
Expand All @@ -18,6 +19,7 @@ interface Dependencies {
emitAppEvent: EmitAppEvent;
logger: Logger;
showErrorNotification: ShowNotification;
closeFileLogging: () => void;
}

const logPrefix = "[CLUSTER-FRAME]:";
Expand All @@ -30,6 +32,7 @@ export const initClusterFrame = ({
emitAppEvent,
logger,
showErrorNotification,
closeFileLogging,
}: Dependencies) =>
async (unmountRoot: () => void) => {
// TODO: Make catalogEntityRegistry already initialized when passed as dependency
Expand Down Expand Up @@ -73,11 +76,14 @@ export const initClusterFrame = ({
});
});

window.onbeforeunload = () => {
const onCloseFrame = once(() => {
logger.info(
`${logPrefix} Unload dashboard, clusterId=${(hostedCluster.id)}, frameId=${frameRoutingId}`,
);

closeFileLogging();
unmountRoot();
};
});

window.addEventListener("beforeunload", onCloseFrame);
window.addEventListener("pagehide", onCloseFrame);
};
Expand Up @@ -13,6 +13,7 @@ import loggerInjectable from "../../../common/logger.injectable";
import { delay } from "../../../common/utils";
import { broadcastMessage } from "../../../common/ipc";
import { bundledExtensionsLoaded } from "../../../common/ipc/extension-handling";
import closeRendererLogFileInjectable from "../../logger/close-renderer-log-file.injectable";

const initRootFrameInjectable = getInjectable({
id: "init-root-frame",
Expand All @@ -24,6 +25,7 @@ const initRootFrameInjectable = getInjectable({
const lensProtocolRouterRenderer = di.inject(lensProtocolRouterRendererInjectable);
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
const logger = di.inject(loggerInjectable);
const closeRendererLogFile = di.inject(closeRendererLogFileInjectable);

return async (unmountRoot: () => void) => {
catalogEntityRegistry.init();
Expand Down Expand Up @@ -59,7 +61,7 @@ const initRootFrameInjectable = getInjectable({

window.addEventListener("beforeunload", () => {
logger.info("[ROOT-FRAME]: Unload app");

closeRendererLogFile();
unmountRoot();
});
};
Expand Down
@@ -0,0 +1,22 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import winstonLoggerInjectable from "../../common/winston-logger.injectable";
import rendererFileLoggerTransportInjectable from "./file-transport.injectable";

const closeRendererLogFileInjectable = getInjectable({
id: "close-renderer-log-file",
instantiate: (di) => {
const winstonLogger = di.inject(winstonLoggerInjectable);
const fileLoggingTransport = di.inject(rendererFileLoggerTransportInjectable);

return () => {
fileLoggingTransport.close?.();
winstonLogger.remove(fileLoggingTransport);
};
},
});

export default closeRendererLogFileInjectable;
44 changes: 44 additions & 0 deletions packages/core/src/renderer/logger/file-transport.injectable.ts
@@ -0,0 +1,44 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { transports } from "winston";
import directoryForLogsInjectable from "../../common/app-paths/directory-for-logs.injectable";
import { loggerTransportInjectionToken } from "../../common/logger/transports";
import windowLocationInjectable from "../../common/k8s-api/window-location.injectable";
import currentlyInClusterFrameInjectable from "../routes/currently-in-cluster-frame.injectable";
import { getClusterIdFromHost } from "../utils";

const rendererFileLoggerTransportInjectable = getInjectable({
id: "renderer-file-logger-transport",
instantiate: (di) => {
let frameId: string;

const currentlyInClusterFrame = di.inject(
currentlyInClusterFrameInjectable,
);

if (currentlyInClusterFrame) {
const { host } = di.inject(windowLocationInjectable);
const clusterId = getClusterIdFromHost(host);

frameId = clusterId ? `cluster-${clusterId}` : "cluster";
} else {
frameId = "main";
}

return new transports.File({
handleExceptions: false,
level: "info",
filename: `lens-renderer-${frameId}.log`,
dirname: di.inject(directoryForLogsInjectable),
maxsize: 1024 * 1024,
maxFiles: 2,
tailable: true,
});
},
injectionToken: loggerTransportInjectionToken,
});

export default rendererFileLoggerTransportInjectable;

0 comments on commit ac2d0e4

Please sign in to comment.