Skip to content

Commit b32e074

Browse files
awschristourli
authored andcommitted
Logger activation is more consistent with other activation code, no longer tailored for use by tests (#784)
1 parent 5232119 commit b32e074

File tree

3 files changed

+56
-93
lines changed

3 files changed

+56
-93
lines changed

src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { EnvironmentVariables } from './shared/environmentVariables'
2121
import { ext } from './shared/extensionGlobals'
2222
import { safeGet, showQuickStartWebview, toastNewUser } from './shared/extensionUtilities'
2323
import { getLogger } from './shared/logger'
24-
import { initialize as activateLogger } from './shared/logger/activation'
24+
import { activate as activateLogger } from './shared/logger/activation'
2525
import { DefaultRegionProvider } from './shared/regions/defaultRegionProvider'
2626
import { activate as activateServerless } from './shared/sam/activation'
2727
import { DefaultSettingsConfiguration } from './shared/settingsConfiguration'

src/shared/logger/activation.ts

Lines changed: 41 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as os from 'os'
88
import * as path from 'path'
99
import * as vscode from 'vscode'
1010
import * as nls from 'vscode-nls'
11-
import { getLogger, Logger, LogLevel } from '.'
11+
import { Logger, LogLevel } from '.'
1212
import { extensionSettingsPrefix } from '../constants'
1313
import { mkdir } from '../filesystem'
1414
import { fileExists } from '../filesystemUtilities'
@@ -19,113 +19,54 @@ import { WinstonToolkitLogger } from './winstonToolkitLogger'
1919

2020
const localize = nls.loadMessageBundle()
2121

22-
const LOG_RELATIVE_PATH: string = path.join('Code', 'logs', 'aws_toolkit')
22+
const LOG_PATH = path.join(getLogBasePath(), 'Code', 'logs', 'aws_toolkit', makeLogFilename())
2323
const DEFAULT_LOG_LEVEL: LogLevel = 'info'
24-
const DEFAULT_LOG_NAME: string = makeDefaultLogName()
25-
const DEFAULT_OUTPUT_CHANNEL: vscode.OutputChannel = vscode.window.createOutputChannel('AWS Toolkit Logs')
24+
const LOG_OUTPUT_CHANNEL: vscode.OutputChannel = vscode.window.createOutputChannel('AWS Toolkit Logs')
2625

2726
/**
28-
* logPath is not required (as Winston will work without a file path defined) but will output errors to stderr.
27+
* Activate Logger functionality for the extension.
2928
*/
30-
export interface LoggerParams {
31-
outputChannel?: vscode.OutputChannel
32-
logPath?: string
33-
logLevel?: LogLevel
34-
}
29+
export async function activate(): Promise<void> {
30+
const outputChannel = LOG_OUTPUT_CHANNEL
31+
const logPath = LOG_PATH
32+
const logLevel = getLogLevel()
3533

36-
/**
37-
* @param params: LoggerParams
38-
* Creates the "default logger" (returnable here and through getLogger) using specified parameters or default values.
39-
* Initializing again will create a new default logger
40-
* --however, existing logger objects using the old default logger will be unaffected.
41-
*/
42-
export async function initialize(params?: LoggerParams): Promise<Logger> {
43-
let outputChannel: vscode.OutputChannel | undefined
44-
let logPath: string | undefined
45-
46-
if (!params) {
47-
outputChannel = DEFAULT_OUTPUT_CHANNEL
48-
logPath = getDefaultLogPath()
49-
50-
const logFolder = path.dirname(logPath)
51-
if (!(await fileExists(logFolder))) {
52-
await mkdir(logFolder, { recursive: true })
53-
}
54-
55-
// TODO : Determine log level here, then createLogger calls in this method can converge
56-
setLogger(
57-
createLogger({
58-
outputChannel,
59-
logPath
60-
})
61-
)
62-
// only the default logger (with default params) gets a registered command
63-
// check list of registered commands to see if aws.viewLogs has already been registered.
64-
// if so, don't register again--this will cause an error visible to the user.
65-
for (const command of await vscode.commands.getCommands(true)) {
66-
if (command === 'aws.viewLogs') {
67-
return getLogger()
68-
}
69-
}
70-
registerCommand({
71-
command: 'aws.viewLogs',
72-
callback: async () => await vscode.window.showTextDocument(vscode.Uri.file(path.normalize(logPath!)))
73-
})
74-
} else {
75-
outputChannel = params.outputChannel
76-
logPath = params.logPath
34+
await ensureLogFolderExists(path.dirname(logPath))
7735

78-
setLogger(createLogger(params))
79-
}
36+
setLogger(makeLogger(logLevel, logPath, outputChannel))
8037

81-
if (outputChannel && logPath) {
82-
outputChannel.appendLine(
83-
localize('AWS.log.fileLocation', 'Error logs for this session are permanently stored in {0}', logPath)
84-
)
85-
}
38+
await registerLoggerCommands()
8639

87-
return getLogger()
40+
outputChannel.appendLine(
41+
localize('AWS.log.fileLocation', 'Error logs for this session are permanently stored in {0}', logPath)
42+
)
8843
}
8944

90-
/**
91-
* @param params: LoggerParams--nothing is required, but a LogPath is highly recommended so Winston doesn't throw errors
92-
*
93-
* Outputs a logger object that isn't stored anywhere--it's up to the caller to keep track of this.
94-
*/
95-
export function createLogger(params: LoggerParams): Logger {
96-
// TODO : log level should be a concern of the caller
97-
let level: LogLevel
98-
if (params.logLevel) {
99-
level = params.logLevel
100-
} else {
101-
const configuration: SettingsConfiguration = new DefaultSettingsConfiguration(extensionSettingsPrefix)
102-
const setLevel = configuration.readSetting<string>('logLevel')
103-
level = setLevel ? (setLevel as LogLevel) : DEFAULT_LOG_LEVEL
104-
}
45+
export function makeLogger(logLevel: LogLevel, logPath: string, outputChannel: vscode.OutputChannel): Logger {
46+
const logger = new WinstonToolkitLogger(logLevel)
47+
logger.logToFile(logPath)
48+
logger.logToOutputChannel(outputChannel)
10549

106-
const logger = new WinstonToolkitLogger(level)
107-
if (params.logPath) {
108-
logger.logToFile(params.logPath)
109-
}
50+
return logger
51+
}
11052

111-
if (params.outputChannel) {
112-
logger.logToOutputChannel(params.outputChannel)
113-
}
53+
function getLogLevel(): LogLevel {
54+
const configuration: SettingsConfiguration = new DefaultSettingsConfiguration(extensionSettingsPrefix)
11455

115-
return logger
56+
return configuration.readSetting<LogLevel>('logLevel', DEFAULT_LOG_LEVEL)
11657
}
11758

118-
function getDefaultLogPath(): string {
59+
function getLogBasePath(): string {
11960
if (os.platform() === 'win32') {
120-
return path.join(os.homedir(), 'AppData', 'Roaming', LOG_RELATIVE_PATH, DEFAULT_LOG_NAME)
61+
return path.join(os.homedir(), 'AppData', 'Roaming')
12162
} else if (os.platform() === 'darwin') {
122-
return path.join(os.homedir(), 'Library', 'Application Support', LOG_RELATIVE_PATH, DEFAULT_LOG_NAME)
63+
return path.join(os.homedir(), 'Library', 'Application Support')
12364
} else {
124-
return path.join(os.homedir(), '.config', LOG_RELATIVE_PATH, DEFAULT_LOG_NAME)
65+
return path.join(os.homedir(), '.config')
12566
}
12667
}
12768

128-
function makeDefaultLogName(): string {
69+
function makeLogFilename(): string {
12970
const m = moment()
13071
const date = m.format('YYYYMMDD')
13172
const time = m.format('HHmmss')
@@ -134,3 +75,16 @@ function makeDefaultLogName(): string {
13475

13576
return `aws_toolkit_${datetime}.log`
13677
}
78+
79+
async function ensureLogFolderExists(logFolder: string): Promise<void> {
80+
if (!(await fileExists(logFolder))) {
81+
await mkdir(logFolder, { recursive: true })
82+
}
83+
}
84+
85+
async function registerLoggerCommands(): Promise<void> {
86+
registerCommand({
87+
command: 'aws.viewLogs',
88+
callback: async () => await vscode.window.showTextDocument(vscode.Uri.file(path.normalize(LOG_PATH)))
89+
})
90+
}

src/test/shared/logger/activation.test.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,30 @@
44
*/
55

66
import * as assert from 'assert'
7+
import * as del from 'del'
8+
import { join } from 'path'
9+
import { makeTemporaryToolkitFolder } from '../../../shared/filesystemUtilities'
710
import { Logger } from '../../../shared/logger'
8-
import { createLogger } from '../../../shared/logger/activation'
11+
import { makeLogger } from '../../../shared/logger/activation'
912
import { WinstonToolkitLogger } from '../../../shared/logger/winstonToolkitLogger'
13+
import { MockOutputChannel } from '../../mockOutputChannel'
1014

11-
describe('createLogger', () => {
15+
describe('makeLogger', () => {
16+
let tempFolder: string
1217
let testLogger: Logger | undefined
1318

1419
before(async () => {
15-
testLogger = createLogger({
16-
logLevel: 'debug'
17-
})
20+
tempFolder = await makeTemporaryToolkitFolder()
21+
testLogger = makeLogger('debug', join(tempFolder, 'log.txt'), new MockOutputChannel())
1822
})
1923

2024
after(async () => {
25+
if (testLogger && testLogger instanceof WinstonToolkitLogger) {
26+
testLogger.dispose()
27+
}
28+
2129
testLogger = undefined
30+
await del([tempFolder], { force: true })
2231
})
2332

2433
it('creates a logger object', () => {

0 commit comments

Comments
 (0)