Skip to content

Commit

Permalink
improvement(logger): add ActionLog (v0)
Browse files Browse the repository at this point in the history
  • Loading branch information
eysi09 authored and thsig committed Mar 28, 2023
1 parent 8dc35a2 commit d51a787
Show file tree
Hide file tree
Showing 126 changed files with 1,252 additions and 886 deletions.
2 changes: 1 addition & 1 deletion cli/src/add-version-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { TreeCache } from "@garden-io/core/build/src/cache"
require("source-map-support").install()

// make sure logger is initialized
Logger.initialize({ level: LogLevel.info, type: "quiet", storeEntries: false })
Logger.initialize({ level: LogLevel.info, terminalWriterType: "quiet", storeEntries: false })

/**
* Write .garden-version files for modules in garden-system/static.
Expand Down
2 changes: 1 addition & 1 deletion cli/src/generate-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ require("source-map-support").install()
try {
Logger.initialize({
level: LogLevel.info,
type: "quiet",
terminalWriterType: "quiet",
storeEntries: false,
// level: LogLevel.debug,
// writers: [new TerminalWriter()],
Expand Down
3 changes: 2 additions & 1 deletion core/src/actions/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,8 @@ export abstract class ExecutedRuntimeAction<
O extends {} = any
>
extends ResolvedRuntimeAction<C, O>
implements ExecutedActionExtension<C, O> {
implements ExecutedActionExtension<C, O>
{
private readonly status: ActionStatus<this, any, O>

constructor(params: ExecutedActionWrapperParams<C, O>) {
Expand Down
6 changes: 4 additions & 2 deletions core/src/actions/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ export class ResolvedBuildAction<
Outputs extends {} = any
>
extends BuildAction<C, Outputs>
implements ResolvedActionExtension<C, Outputs> {
implements ResolvedActionExtension<C, Outputs>
{
protected graph: ResolvedConfigGraph
protected readonly params: ResolvedActionWrapperParams<C>
protected readonly resolved: true
Expand Down Expand Up @@ -239,7 +240,8 @@ export class ExecutedBuildAction<
O extends {} = any
>
extends ResolvedBuildAction<C, O>
implements ExecutedActionExtension<C, O> {
implements ExecutedActionExtension<C, O>
{
protected readonly executed: true
private readonly status: ActionStatus<this, any, O>

Expand Down
140 changes: 57 additions & 83 deletions core/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ import { resolve, join } from "path"
import chalk from "chalk"
import { pathExists } from "fs-extra"
import { getBuiltinCommands } from "../commands/commands"
import { shutdown, sleep, getPackageVersion, registerCleanupFunction, getCloudDistributionName } from "../util/util"
import {
shutdown,
sleep,
getPackageVersion,
registerCleanupFunction,
getCloudDistributionName,
getCloudLogSectionName,
} from "../util/util"
import { Command, CommandResult, CommandGroup, BuiltinArgs } from "../commands/base"
import { PluginError, toGardenError, GardenBaseError } from "../exceptions"
import { Garden, GardenOpts, DummyGarden } from "../garden"
import { Logger, LoggerType, LogLevel, parseLogLevel } from "../logger/logger"
import { getTerminalWriterType, Logger, LogLevel, parseLogLevel } from "../logger/logger"
import { FileWriter, FileWriterConfig } from "../logger/writers/file-writer"

import {
Expand Down Expand Up @@ -61,7 +68,6 @@ import { prepareDebugLogfiles } from "./debug-logs"
import { Log } from "../logger/log-entry"
import { JsonFileWriter } from "../logger/writers/json-file-writer"
import { dedent } from "../util/string"
import { printEmoji, renderDivider } from "../logger/util"
import { GardenProcess, GlobalConfigStore } from "../config-store/global"
import { registerProcess } from "../process"
import { ServeCommand } from "../commands/serve"
Expand Down Expand Up @@ -89,27 +95,6 @@ export async function makeDummyGarden(root: string, gardenOpts: GardenOpts) {
return DummyGarden.factory(root, { noEnterprise: true, ...gardenOpts })
}

function renderHeader({
environmentName,
namespaceName,
log,
}: {
environmentName: string
namespaceName: string
log: Log
}) {
const divider = chalk.gray(renderDivider())
let msg = `${printEmoji("🌍", log)} Running in namespace ${chalk.cyan(namespaceName)} in environment ${chalk.cyan(
environmentName
)}`

return dedent`
${divider}
${msg}
${divider}\n
`
}

export interface RunOutput {
argv: any
code: number
Expand Down Expand Up @@ -160,12 +145,10 @@ ${renderCommands(commands)}
}

private async initFileWriters({
logger,
log,
gardenDirPath,
commandFullName,
}: {
logger: Logger
log: Log
gardenDirPath: string
commandFullName: string
Expand Down Expand Up @@ -201,11 +184,11 @@ ${renderCommands(commands)}
},
{
logFilePath: join(gardenDirPath, LOGS_DIR_NAME, "development.log"),
level: logger.level,
level: log.root.level,
},
]
for (const config of logConfigs) {
logger.addWriter(await (config.json ? JsonFileWriter : FileWriter).factory(config))
log.root.addFileWriter(await (config.json ? JsonFileWriter : FileWriter).factory(config))
}
this.fileWritersInitialized = true
}
Expand Down Expand Up @@ -241,21 +224,20 @@ ${renderCommands(commands)}
parsedOpts,
processRecord,
workingDir,
log,
}: {
command: Command<A, O>
parsedArgs: BuiltinArgs & ParameterValues<A>
parsedOpts: ParameterValues<GlobalOptions & O>
processRecord?: GardenProcess
workingDir: string
log: Log
}) {
const {
"logger-type": loggerTypeOpt,
"log-level": logLevel,
"show-timestamps": showTimestamps,
emoji,
"env": environmentName,
silent,
output,
"logger-type": loggerTypeOpt,
"env": environmentName,
"force-refresh": forceRefresh,
"var": cliVars,
"disable-port-forwards": disablePortForwards,
Expand All @@ -264,33 +246,10 @@ ${renderCommands(commands)}
// Parse command line --var input
const parsedCliVars = cliVars ? dotenv.parse(cliVars.join("\n")) : {}

// Init logger
const level = parseLogLevel(logLevel)
let loggerType = <LoggerType>loggerTypeOpt || command.getLoggerType({ opts: parsedOpts, args: parsedArgs })

if (silent || output) {
loggerType = "quiet"
}

const logger = Logger.initialize(
{
level,
storeEntries: false,
type: loggerType,
useEmoji: emoji,
showTimestamps,
},
// May need to overwrite here
this.initLogger
)

// Currently we initialise empty placeholder entries and pass those to the
// framework as opposed to the logger itself. This is to give better control over where on
// the screen the logs are printed.
// TODO: Remove header and footer logs. Not needed any more.
const headerLog = logger.makeNewLogContext()
const log = logger.makeNewLogContext()
const footerLog = logger.makeNewLogContext()
// Some commands may set their own logger type so we update the logger config here,
// once we've resolved the command.
const commandLoggerType = command.getTerminalWriterType({ opts: parsedOpts, args: parsedArgs })
log.root.setTerminalWriter(getTerminalWriterType({ silent, output, loggerTypeOpt, commandLoggerType }))

// TODO: remove for the proper 0.13 release
if (!gardenEnv.GARDEN_DISABLE_VERSION_CHECK && new SemVer(getPackageVersion()).minor === 13) {
Expand All @@ -304,7 +263,7 @@ ${renderCommands(commands)}

await validateRuntimeRequirementsCached(log, globalConfigStore, checkRequirements)

command.printHeader({ headerLog, args: parsedArgs, opts: parsedOpts })
command.printHeader({ headerLog: log, args: parsedArgs, opts: parsedOpts })
const sessionId = uuidv4()

// Init Cloud API
Expand Down Expand Up @@ -378,8 +337,8 @@ ${renderCommands(commands)}

const prepareParams = {
log,
headerLog,
footerLog,
headerLog: log,
footerLog: log,
args: parsedArgs,
opts: parsedOpts,
cloudApi: cloudApi || undefined,
Expand All @@ -394,7 +353,7 @@ ${renderCommands(commands)}
contextOpts.persistent = persistent
const { streamEvents, streamLogEntries } = command
// TODO: Link to Cloud namespace page here.
const nsLog = headerLog.makeNewLogContext({})
const nsLog = log.createLog({})

do {
try {
Expand All @@ -403,7 +362,12 @@ ${renderCommands(commands)}
} else {
garden = await this.getGarden(workingDir, contextOpts)

nsLog.info(renderHeader({ namespaceName: garden.namespace, environmentName: garden.environmentName, log }))
nsLog.info({
section: "garden",
msg: `Running in namespace ${chalk.cyan(garden.namespace)} in environment ${chalk.cyan(
garden.environmentName
)}`,
})

if (!cloudApi && garden.projectId) {
log.warn({
Expand Down Expand Up @@ -452,13 +416,11 @@ ${renderCommands(commands)}
const distroName = getCloudDistributionName(cloudApi.domain)
const userId = (await cloudApi.getProfile()).id
const commandResultUrl = cloudApi.getCommandResultUrl({ sessionId, userId }).href
const msg = dedent`
\n${printEmoji("🌩️", log)} ${chalk.cyan(
`Connected to ${distroName}! Click the link below to view logs and command results.`
)}
${printEmoji("🔗", log)} ${chalk.blueBright.underline(commandResultUrl)}
`
footerLog.info(msg)

const msg = dedent`🌸 Connected to ${distroName}. View logs and command results at: \n\n${chalk.cyan(
commandResultUrl
)}\n`
log.info({ section: getCloudLogSectionName(distroName), msg })
}
}

Expand Down Expand Up @@ -496,7 +458,6 @@ ${renderCommands(commands)}
// Register log file writers. We need to do this after the Garden class is initialised because
// the file writers depend on the project root.
await this.initFileWriters({
logger,
log,
gardenDirPath: garden.gardenDirPath,
commandFullName: command.getFullName(),
Expand All @@ -505,9 +466,9 @@ ${renderCommands(commands)}
analytics.trackCommand(command.getFullName())

// Note: No reason to await the check
checkForUpdates(garden.globalConfigStore, headerLog).catch((err) => {
headerLog.verbose("Something went wrong while checking for the latest Garden version.")
headerLog.verbose(err)
checkForUpdates(garden.globalConfigStore, log).catch((err) => {
log.verbose("Something went wrong while checking for the latest Garden version.")
log.verbose(err)
})

await checkForStaticDir()
Expand All @@ -520,8 +481,8 @@ ${renderCommands(commands)}
garden,
cli: this,
log,
footerLog,
headerLog,
footerLog: log,
headerLog: log,
args: parsedArgs,
opts: parsedOpts,
})
Expand Down Expand Up @@ -603,14 +564,27 @@ ${renderCommands(commands)}
// First look for native Garden commands
let { command, rest, matchedPath } = pickCommand(Object.values(this.commands), argv._)

// Logger might not have been initialised if process exits early
// Note: We partially initialize the logger here with the default writer or the one set via
// command line flags / env var by the user so that we can use it right away.
// Some commands require a specific writer so we update the writers (if needed) once
// we've resolved the commands.
const {
emoji,
silent,
output,
"show-timestamps": showTimestamps,
"logger-type": loggerTypeOpt,
"log-level": logLevelStr,
} = argv
const logger = Logger.initialize({
level: LogLevel.info,
type: "default",
level: parseLogLevel(logLevelStr),
storeEntries: false,
terminalWriterType: getTerminalWriterType({ silent, output, loggerTypeOpt, commandLoggerType: null }),
useEmoji: emoji,
showTimestamps,
})

const log = logger.makeNewLogContext()
const log = logger.createLog()

// Load custom commands from current project (if applicable) and see if any match the arguments
if (!command) {
Expand Down Expand Up @@ -686,7 +660,7 @@ ${renderCommands(commands)}
const commandStartTime = new Date()

try {
const runResults = await this.runCommand({ command, parsedArgs, parsedOpts, processRecord, workingDir })
const runResults = await this.runCommand({ command, parsedArgs, parsedOpts, processRecord, workingDir, log })
commandResult = runResults.result
analytics = runResults.analytics
} catch (err) {
Expand Down
5 changes: 2 additions & 3 deletions core/src/cli/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { globalOptions, GlobalOptions } from "./params"
import { BuiltinArgs, Command, CommandGroup } from "../commands/base"
import { DeepPrimitiveMap } from "../config/common"
import { validateGitInstall } from "../vcs/vcs"
import { FileWriter } from "../logger/writers/file-writer"

export const cliStyles = {
heading: (str: string) => chalk.white.bold(str),
Expand Down Expand Up @@ -487,7 +486,7 @@ function renderParameters(params: Parameters, formatName: (name: string, param:
export function renderCommandErrors(logger: Logger, errors: Error[], log?: Log) {
const gardenErrors: GardenBaseError[] = errors.map(toGardenError)

const errorLog = log || logger.makeNewLogContext()
const errorLog = log || logger.createLog()

for (const error of gardenErrors) {
errorLog.error({
Expand All @@ -498,7 +497,7 @@ export function renderCommandErrors(logger: Logger, errors: Error[], log?: Log)
errorLog.silly(error.formatWithDetail())
}

if (logger.getWriters().find((w) => w instanceof FileWriter)) {
if (logger.getWriters().file.length > 0) {
errorLog.info(`\nSee .garden/${ERROR_LOG_FILENAME} for detailed error message`)
}
}
9 changes: 3 additions & 6 deletions core/src/cli/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,7 @@ export function describeParameters(args?: Parameters) {

export const globalOptions = {
"root": new PathParameter({
help:
"Override project root directory (defaults to working directory). Can be absolute or relative to current directory.",
help: "Override project root directory (defaults to working directory). Can be absolute or relative to current directory.",
}),
"silent": new BooleanParameter({
help: "Suppress log output. Same as setting --logger-type=quiet.",
Expand Down Expand Up @@ -436,8 +435,7 @@ export const globalOptions = {
defaultValue: false,
}),
"var": new StringsParameter({
help:
'Set a specific variable value, using the format <key>=<value>, e.g. `--var some-key=custom-value`. This will override any value set in your project configuration. You can specify multiple variables by separating with a comma, e.g. `--var key-a=foo,key-b="value with quotes"`.',
help: 'Set a specific variable value, using the format <key>=<value>, e.g. `--var some-key=custom-value`. This will override any value set in your project configuration. You can specify multiple variables by separating with a comma, e.g. `--var key-a=foo,key-b="value with quotes"`.',
}),
"version": new BooleanParameter({
aliases: ["V"],
Expand All @@ -448,8 +446,7 @@ export const globalOptions = {
help: "Show help",
}),
"disable-port-forwards": new BooleanParameter({
help:
"Disable automatic port forwarding when in watch mode. Note that you can also set GARDEN_DISABLE_PORT_FORWARDS=true in your environment.",
help: "Disable automatic port forwarding when in watch mode. Note that you can also set GARDEN_DISABLE_PORT_FORWARDS=true in your environment.",
}),
}

Expand Down
Loading

0 comments on commit d51a787

Please sign in to comment.