Skip to content

Commit

Permalink
feat(logger): add logger module replace log4js
Browse files Browse the repository at this point in the history
  • Loading branch information
chemzqm committed Nov 2, 2022
1 parent a182d95 commit c76d47f
Show file tree
Hide file tree
Showing 154 changed files with 629 additions and 363 deletions.
25 changes: 1 addition & 24 deletions esbuild.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
const cp = require('child_process')
const fs = require('fs')
const path = require('path')
let revision = 'master'
if (process.env.NODE_ENV !== 'development') {
try {
Expand All @@ -11,26 +9,6 @@ if (process.env.NODE_ENV !== 'development') {
}
}

let envPlugin = {
name: 'env',
setup(build) {
build.onResolve({filter: /\/appenders$/}, args => {
let fullpath = path.join(args.resolveDir, args.path)
return {
path: path.relative(__dirname, fullpath).replace(/\\/g, '/'),
namespace: 'env-ns'
}
})
build.onLoad({filter: /^node_modules\/log4js\/lib\/appenders$/, namespace: 'env-ns'}, args => {
let content = fs.readFileSync(path.join(args.path, 'index.js'), 'utf8')
return {
contents: content.replace(/require\.main/g, '""'),
resolveDir: args.path
}
})
}
}

async function start(watch) {
await require('esbuild').build({
entryPoints: ['src/main.ts'],
Expand All @@ -42,8 +20,7 @@ async function start(watch) {
mainFields: ['module', 'main'],
platform: 'node',
target: 'node14.14',
outfile: 'build/index.js',
plugins: [envPlugin]
outfile: 'build/index.js'
})
}

Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.0",
"jsonc-parser": "^3.0.0",
"log4js": "^6.4.0",
"marked": "^4.0.12",
"minimatch": "^5.1.0",
"semver": "^7.3.2",
Expand Down
198 changes: 198 additions & 0 deletions src/__tests__/modules/logger.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import { FileLogger, toTwoDigits, toThreeDigits, textToLogLevel, format, DEFAULT_LOG_LEVEL, LogLevel } from '../../logger/log'
import { createLogger, resolveLogFilepath, emptyFile } from '../../logger/index'
import path from 'path'
import fs from 'fs'
import os from 'os'
import { v4 as uuid } from 'uuid'

let filepath: string
afterEach(() => {
if (fs.existsSync(filepath)) fs.unlinkSync(filepath)
})

describe('FileLogger', () => {
it('should have DEFAULT_LOG_LEVEL', () => {
expect(DEFAULT_LOG_LEVEL).toBeDefined()
})

it('should convert digits', () => {
expect(toTwoDigits(1)).toBe('01')
expect(toTwoDigits(11)).toBe('11')
expect(toThreeDigits(1)).toBe('001')
expect(toThreeDigits(10)).toBe('010')
expect(toThreeDigits(100)).toBe('100')
})

it('should get level from text', () => {
expect(textToLogLevel('trace')).toBe(LogLevel.Trace)
expect(textToLogLevel('debug')).toBe(LogLevel.Debug)
expect(textToLogLevel('info')).toBe(LogLevel.Info)
expect(textToLogLevel('error')).toBe(LogLevel.Error)
expect(textToLogLevel('warning')).toBe(LogLevel.Warning)
expect(textToLogLevel('warn')).toBe(LogLevel.Warning)
expect(textToLogLevel('off')).toBe(LogLevel.Off)
expect(textToLogLevel('')).toBe(LogLevel.Info)
})

it('should format', () => {
let obj = {
x: 1,
y: '2',
z: {}
} as any
obj.z.parent = obj
let res = format([obj], 2, true, false)
expect(res).toBeDefined()
res = format([obj])
expect(res).toBeDefined()
})

it('should create logger', async () => {
filepath = path.join(os.tmpdir(), uuid())
let fileLogger = new FileLogger(filepath, LogLevel.Trace, {
color: false,
depth: 2,
showHidden: false,
userFormatters: true
})
let logger = fileLogger.createLogger('scope')
logger.log('msg')
logger.trace('trace', 'data', {}, 1, true)
logger.debug('debug')
logger.info('info')
logger.warn('warn')
logger.error('error')
logger.fatal('fatal')
logger.mark('mark')
await logger.flush()
let content = fs.readFileSync(filepath, 'utf8')
let lines = content.split(/\n/)
expect(lines.length).toBe(8)
expect(logger.category).toBeDefined()
expect(logger.level).toBeDefined()
expect(logger.getLevel()).toBeDefined()
})

it('should enable color', async () => {
filepath = path.join(os.tmpdir(), uuid())
let fileLogger = new FileLogger(filepath, LogLevel.Trace, {
color: true
})
let logger = fileLogger.createLogger('scope')
logger.info('msg', 1, true, { foo: 'bar' })
await logger.flush()
let content = fs.readFileSync(filepath, 'utf8')
expect(content.indexOf('\x33')).toBeGreaterThan(-1)
})

it('should change level', () => {
filepath = path.join(os.tmpdir(), uuid())
let fileLogger = new FileLogger(filepath, LogLevel.Off, {})
let fn = jest.fn()
fileLogger.onDidChangeLogLevel(() => {
fn()
})
fileLogger.setLevel(LogLevel.Debug)
fileLogger.setLevel(LogLevel.Debug)
expect(fn).toBeCalledTimes(1)
})

it('should work with off level', async () => {
filepath = path.join(os.tmpdir(), uuid())
let fileLogger = new FileLogger(filepath, LogLevel.Off, {
color: false,
depth: 2,
showHidden: false,
userFormatters: true
})
let logger = fileLogger.createLogger('scope')
logger.log('msg')
logger.trace('trace')
logger.debug('debug')
logger.info('info')
logger.warn('warn')
logger.error('error')
logger.fatal('fatal')
logger.mark('mark')
await logger.flush()
expect(fs.existsSync(filepath)).toBe(false)
expect(logger.level).toBeDefined()
})

it('should work without formatter', async () => {
filepath = path.join(os.tmpdir(), uuid())
let fileLogger = new FileLogger(filepath, LogLevel.Trace, {
userFormatters: false
})
let logger = fileLogger.createLogger('scope')
logger.log('msg\n')
await logger.flush()
let content = fs.readFileSync(filepath, 'utf8')
let lines = content.split(/\n/)
expect(lines.length).toBe(2)
})

it('should use backup file', async () => {
filepath = path.join(os.tmpdir(), uuid())
let fileLogger = new FileLogger(filepath, LogLevel.Trace, {
userFormatters: true
})
let logger = fileLogger.createLogger('scope')
let spy = jest.spyOn(fileLogger, 'shouldBackup').mockImplementation(() => {
return true
})
for (let i = 0; i < 6; i++) {
logger.log(1)
}
await logger.flush()
spy.mockRestore()
let newFile = filepath + `_1`
expect(fs.existsSync(newFile)).toBe(true)
})

it('should not throw on error', async () => {
filepath = path.join(os.tmpdir(), uuid())
let fileLogger = new FileLogger(filepath, LogLevel.Trace, {
userFormatters: false
})
let logger = fileLogger.createLogger('scope')
let fn = jest.fn()
let s = jest.spyOn(console, 'error').mockImplementation(() => {
fn()
})
let spy = jest.spyOn(fileLogger, 'shouldBackup').mockImplementation(() => {
throw new Error('my error')
})
logger.log('msg\n')
await logger.flush()
expect(fn).toBeCalled()
s.mockRestore()
spy.mockRestore()
})

it('should create default logger', () => {
expect(createLogger()).toBeDefined()
})

it('should resolveLogFilepath from env', () => {
let filepath = '/tmp/log'
process.env.NVIM_COC_LOG_FILE = filepath
expect(resolveLogFilepath()).toBe(filepath)
process.env.NVIM_COC_LOG_FILE = ''
process.env.XDG_RUNTIME_DIR = os.tmpdir()
expect(resolveLogFilepath()).toBeDefined()
process.env.XDG_RUNTIME_DIR = '/dir_not_exists'
expect(resolveLogFilepath()).toBeDefined()
process.env.XDG_RUNTIME_DIR = ''
expect(resolveLogFilepath()).toBeDefined()
})

it('should empty file', async () => {
emptyFile('/file_not_exists')
filepath = path.join(os.tmpdir(), uuid())
fs.writeFileSync(filepath, 'data', 'utf8')
emptyFile(filepath)
let content = fs.readFileSync(filepath, 'utf8')
expect(content.trim().length).toBe(0)
})
})
13 changes: 0 additions & 13 deletions src/__tests__/modules/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import { Sequence } from '../../util/sequence'
import * as strings from '../../util/string'
import * as textedits from '../../util/textedit'
import helper from '../helper'
const createLogger = require('../../util/logger')

function createTextDocument(lines: string[]): LinesTextDocument {
return new LinesTextDocument('file://a', 'txt', 1, lines, 1, true)
Expand Down Expand Up @@ -140,18 +139,6 @@ describe('platform', () => {
})
})

describe('logger', () => {
it('should get log file', async () => {
let val = process.env.NVIM_COC_LOG_FILE
process.env.NVIM_COC_LOG_FILE = ''
let logger = createLogger('')
expect(logger.getLogFile()).toBeDefined()
process.env.XDG_RUNTIME_DIR = ''
expect(logger.getLogFile()).toBeDefined()
process.env.NVIM_COC_LOG_FILE = val
})
})

describe('textedit', () => {

function createEdit(uri: string): WorkspaceEdit {
Expand Down
14 changes: 7 additions & 7 deletions src/attach.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
'use strict'
import { attach, Attach, NeovimClient } from '@chemzqm/neovim'
import log4js from 'log4js'
import events from './events'
import Plugin from './plugin'
import semver from 'semver'
import { objectLiteral } from './util/is'
import { URI } from 'vscode-uri'
import { version as VERSION } from '../package.json'
import { createLogger } from './logger'
const logger = createLogger('attach')

const logger = require('./util/logger')('attach')
/**
* Request actions that not need plugin ready
*/
const ACTIONS_NO_WAIT = ['installExtensions', 'updateExtensions']

export default (opts: Attach, requestApi = true): Plugin => {
const nvim: NeovimClient = attach(opts, log4js.getLogger('node-client'), requestApi)
const nvim: NeovimClient = attach(opts, createLogger('node-client'), requestApi)
if (!global.__TEST__) {
nvim.call('coc#util#path_replace_patterns').then(prefixes => {
void nvim.call('coc#util#path_replace_patterns').then(prefixes => {
if (objectLiteral(prefixes)) {
const old_uri = URI.file
URI.file = (path): URI => {
Expand All @@ -26,7 +26,7 @@ export default (opts: Attach, requestApi = true): Plugin => {
return old_uri(path)
}
}
}).logError()
})
}
nvim.setVar('coc_process_pid', process.pid, true)
const plugin = new Plugin(nvim)
Expand All @@ -42,7 +42,7 @@ export default (opts: Attach, requestApi = true): Plugin => {
break
}
case 'Log': {
logger.debug(...args)
logger.debug('Vim log', ...args)
break
}
case 'TaskExit':
Expand Down Expand Up @@ -81,7 +81,7 @@ export default (opts: Attach, requestApi = true): Plugin => {
await plugin.cocAction(method, ...args)
} catch (e) {
nvim.echoError(`Error on notification "${method}": ${(e instanceof Error ? e.message : e)}`)
logger.error(e)
logger.error(`Error on notification ${method}`, e)
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import { toText } from './util/string'
import window from './window'
import workspace from './workspace'

const logger = require('./util/logger')('commands')

// command center
export interface Command {
readonly id: string | string[]
Expand Down
3 changes: 2 additions & 1 deletion src/completion/complete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { byteSlice, characterIndex } from '../util/string'
import { fuzzyScore, fuzzyScoreGracefulAggressive, FuzzyScorer } from '../util/filter'
import { ConvertOption, toDurationCompleteItem } from './util'
import { WordDistance } from './wordDistance'
const logger = require('../util/logger')('completion-complete')
import { createLogger } from '../logger'
const logger = createLogger('completion-complete')
const MAX_DISTANCE = 2 << 20

export interface CompleteConfig {
Expand Down
3 changes: 2 additions & 1 deletion src/completion/floating.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use strict'
import { Neovim } from '@chemzqm/neovim'
import { CancellationToken } from 'vscode-languageserver-protocol'
import { createLogger } from '../logger'
import { parseDocuments } from '../markdown'
import sources from '../sources'
import { CompleteOption, Documentation, DurationCompleteItem, FloatConfig } from '../types'
import { isCancellationError } from '../util/errors'
import workspace from '../workspace'
const logger = require('../util/logger')('completion-floating')
const logger = createLogger('completion-floating')

export default class Floating {
private excludeImages = true
Expand Down
3 changes: 2 additions & 1 deletion src/completion/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Neovim } from '@chemzqm/neovim'
import { CancellationToken, CancellationTokenSource, Disposable, Position } from 'vscode-languageserver-protocol'
import { URI } from 'vscode-uri'
import events, { InsertChange, PopupChangeEvent } from '../events'
import { createLogger } from '../logger'
import Document from '../model/document'
import sources from '../sources'
import { CompleteOption, DurationCompleteItem, IConfigurationChangeEvent, ISource } from '../types'
Expand All @@ -16,7 +17,7 @@ import Floating from './floating'
import MruLoader from './mru'
import PopupMenu, { PopupMenuConfig } from './pum'
import { checkIgnoreRegexps, createKindMap, getInput, getResumeInput, getSources, shouldStop, toCompleteDoneItem } from './util'
const logger = require('../util/logger')('completion')
const logger = createLogger('completion')
const RESOLVE_TIMEOUT = global.__TEST__ ? 50 : 500
const TRIGGER_TIMEOUT = global.__TEST__ ? 20 : 200

Expand Down
1 change: 0 additions & 1 deletion src/completion/mru.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict'
import { DurationCompleteItem } from '../types'
const logger = require('../util/logger')('completion-mru')

export type Selection = 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix'

Expand Down
1 change: 0 additions & 1 deletion src/completion/pum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import workspace from '../workspace'
import { anyScore } from '../util/filter'
import MruLoader, { Selection } from './mru'
import { getKindHighlight, getKindText, getValidWord, highlightOffert } from './util'
const logger = require('../util/logger')('completion-pum')

export interface PumDimension {
readonly height: number
Expand Down
Loading

0 comments on commit c76d47f

Please sign in to comment.