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

improvement(k8s): verbose logging of the local app output in local mode #3050

Merged
merged 3 commits into from
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/plugins/kubernetes/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
23 changes: 19 additions & 4 deletions core/src/plugins/kubernetes/local-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 = []

Expand Down Expand Up @@ -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.`
),
})

Expand Down Expand Up @@ -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 => {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -499,6 +503,17 @@ function getLocalAppProcess(configParams: StartLocalModeParams): RecoverableProc
},
onMessage: (_msg: ProcessMessage) => {},
},
stdoutListener: {
hasErrors: (_chunk: any) => false,
onError: (_msg: ProcessMessage) => {},
vvagaytsev marked this conversation as resolved.
Show resolved Hide resolved
onMessage: (msg: ProcessMessage) => {
log.verbose({
symbol: "info",
section: gardenService.name,
msg: chalk.grey(composeMessage(stripEol(msg.message), msg)),
})
},
},
})
: undefined
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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!
Expand Down Expand Up @@ -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({
Expand All @@ -208,6 +214,7 @@ describe("kubernetes container deployment handlers", () => {
blueGreen: false,
})

expectProxyContainerImage(workload)
expectEmptyContainerArgs(workload)
})

Expand Down
13 changes: 13 additions & 0 deletions docs/guides/running-service-in-local-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.