From 6450936f8b22224ef04083315b0b199c73cbe70c Mon Sep 17 00:00:00 2001 From: Vladimir Vagaytsev Date: Wed, 13 Jul 2022 14:16:08 +0200 Subject: [PATCH] improvement(k8s): verbose logging of the local app output in local mode Additional changes: * refactor: renamed constant * test: added assertion for local-mode config --- core/src/plugins/kubernetes/constants.ts | 2 +- core/src/plugins/kubernetes/local-mode.ts | 23 +++++++++++++++---- .../kubernetes/container/deployment.ts | 9 +++++++- docs/guides/running-service-in-local-mode.md | 13 +++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/core/src/plugins/kubernetes/constants.ts b/core/src/plugins/kubernetes/constants.ts index f4710ef12b..a8e90b32b2 100644 --- a/core/src/plugins/kubernetes/constants.ts +++ b/core/src/plugins/kubernetes/constants.ts @@ -30,7 +30,7 @@ export const dockerDaemonDeploymentName = "garden-docker-daemon" export const k8sUtilImageName = "gardendev/k8s-util:0.5.4" export const k8sSyncUtilImageName = "gardendev/k8s-sync:0.1.5" -export const reverseProxyImageName = "gardendev/k8s-reverse-proxy:0.0.1" +export const k8sReverseProxyImageName = "gardendev/k8s-reverse-proxy:0.0.1" export const dockerDaemonContainerName = "docker-daemon" export const skopeoDaemonContainerName = "util" diff --git a/core/src/plugins/kubernetes/local-mode.ts b/core/src/plugins/kubernetes/local-mode.ts index f43e84b3db..085dc08314 100644 --- a/core/src/plugins/kubernetes/local-mode.ts +++ b/core/src/plugins/kubernetes/local-mode.ts @@ -12,10 +12,10 @@ import { find, remove, set } from "lodash" import { SyncableResource } from "./hot-reload/hot-reload" import { PrimitiveMap } from "../../config/common" import { + k8sReverseProxyImageName, PROXY_CONTAINER_SSH_TUNNEL_PORT, PROXY_CONTAINER_SSH_TUNNEL_PORT_NAME, PROXY_CONTAINER_USER_NAME, - reverseProxyImageName, } from "./constants" import { ConfigurationError, RuntimeError } from "../../exceptions" import { getResourceContainer, prepareEnvVars } from "./util" @@ -322,7 +322,7 @@ function patchSyncableManifest( const targetContainer = getResourceContainer(targetManifest, containerName) // use reverse proxy container image - targetContainer.image = reverseProxyImageName + targetContainer.image = k8sReverseProxyImageName // erase the original container arguments, the proxy container won't recognize them targetContainer.args = [] @@ -367,7 +367,7 @@ export async function configureLocalMode(configParams: ConfigureLocalModeParams) log.debug({ section: gardenService.name, msg: chalk.gray( - `Configuring in local mode, proxy container ${chalk.underline(reverseProxyImageName)} will be deployed.` + `Configuring in local mode, proxy container ${chalk.underline(k8sReverseProxyImageName)} will be deployed.` ), }) @@ -395,7 +395,7 @@ const attemptsLeft = ({ maxRetries, minTimeoutMs, retriesLeft }: RetryInfo): str } const composeMessage = (customMessage: string, processMessage: ProcessMessage): string => { - return `${customMessage} [PID=${processMessage.pid}]` + return `[PID=${processMessage.pid}] ${customMessage}` } const composeErrorMessage = (customMessage: string, processMessage: ProcessMessage): string => { @@ -455,6 +455,10 @@ function getLocalAppProcess(configParams: StartLocalModeParams): RecoverableProc const localServiceCmd = getLocalAppCommand(configParams) const { ctx, gardenService, log } = configParams + // This covers Win \r\n, Linux \n, and MacOS \r line separators. + const eolRegex = /\r?\n?$/ + const stripEol = (message: string) => message.replace(eolRegex, "") + return !!localServiceCmd ? new RecoverableProcess({ osCommand: localServiceCmd, @@ -499,6 +503,17 @@ function getLocalAppProcess(configParams: StartLocalModeParams): RecoverableProc }, onMessage: (_msg: ProcessMessage) => {}, }, + stdoutListener: { + hasErrors: (_chunk: any) => false, + onError: (_msg: ProcessMessage) => {}, + onMessage: (msg: ProcessMessage) => { + log.verbose({ + symbol: "info", + section: gardenService.name, + msg: chalk.grey(composeMessage(stripEol(msg.message), msg)), + }) + }, + }, }) : undefined } diff --git a/core/test/integ/src/plugins/kubernetes/container/deployment.ts b/core/test/integ/src/plugins/kubernetes/container/deployment.ts index 5f472e4b28..db8604e1d9 100644 --- a/core/test/integ/src/plugins/kubernetes/container/deployment.ts +++ b/core/test/integ/src/plugins/kubernetes/container/deployment.ts @@ -31,6 +31,7 @@ import { apply } from "../../../../../../src/plugins/kubernetes/kubectl" import { getAppNamespace } from "../../../../../../src/plugins/kubernetes/namespace" import { gardenAnnotationKey } from "../../../../../../src/util/string" import { + k8sReverseProxyImageName, k8sSyncUtilImageName, PROXY_CONTAINER_SSH_TUNNEL_PORT, PROXY_CONTAINER_SSH_TUNNEL_PORT_NAME, @@ -79,6 +80,11 @@ describe("kubernetes container deployment handlers", () => { expect(appContainerSpec!.args).to.eql([]) } + function expectProxyContainerImage(workload: KubernetesWorkload) { + const appContainerSpec = workload.spec.template?.spec?.containers.find((c) => c.name === "local-mode") + expect(appContainerSpec!.image).to.eql(k8sReverseProxyImageName) + } + function expectContainerEnvVars(workload: KubernetesWorkload) { const appContainerSpec = workload.spec.template?.spec?.containers.find((c) => c.name === "local-mode") const env = appContainerSpec!.env! @@ -193,7 +199,7 @@ describe("kubernetes container deployment handlers", () => { expectSshContainerPort(workload) }) - it("Workflow should have empty container args when in local mode", async () => { + it("Workflow should have proxy container image and empty container args when in local mode", async () => { const service = graph.getService("local-mode") const { workload } = await createContainerManifests({ @@ -208,6 +214,7 @@ describe("kubernetes container deployment handlers", () => { blueGreen: false, }) + expectProxyContainerImage(workload) expectEmptyContainerArgs(workload) }) diff --git a/docs/guides/running-service-in-local-mode.md b/docs/guides/running-service-in-local-mode.md index 3e7a69efaa..35d1079ffb 100644 --- a/docs/guides/running-service-in-local-mode.md +++ b/docs/guides/running-service-in-local-mode.md @@ -178,3 +178,16 @@ _Local mode_ always runs in persistent mode, it means that the Garden process wo explicitly. All port-forwards established by _local mode_ will be stopped on the process exit. The local application will be stopped if it was started via the `localMode.command` configuration option. Otherwise, if the local application was started manually, it will continue running. + +## Watching the local application's logs + +If you run your local application with the `localMode.command` configuration option, then you can easily watch the local +application's logs in real-time by running a `garden` command with `verbose` log level: + +```shell +garden deploy --local -l 3 +# or +garden dev --local -l 3 +``` + +Otherwise, you can find the logs in `.garden/deploy.debug.*.log` files.