Skip to content

Generalize logger usage between src and binary folders #3923

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

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
43140e0
Generalize logger usage between src and binary folders
scorbajio Mar 19, 2025
88d9eea
Merge branch 'master' into client-logger-separation
scorbajio Mar 19, 2025
aa1b2f9
Merge branch 'master' of github.com:ethereumjs/ethereumjs-monorepo in…
scorbajio Mar 19, 2025
9132344
Move logger classes to src directory
scorbajio Mar 19, 2025
2c71939
Merge branch 'client-logger-separation' of github.com:ethereumjs/ethe…
scorbajio Mar 19, 2025
2b2d766
Merge branch 'master' of github.com:ethereumjs/ethereumjs-monorepo in…
scorbajio Mar 20, 2025
c7521cf
fix imports
scorbajio Mar 21, 2025
fb37e05
Fix imports
scorbajio Mar 21, 2025
ab1c557
Fix bind bug
scorbajio Mar 21, 2025
71dc8f0
Merge branch 'master' of github.com:ethereumjs/ethereumjs-monorepo in…
scorbajio Mar 21, 2025
4eb40cd
Fix imports
scorbajio Mar 21, 2025
3972d8f
Fix type error
scorbajio Mar 21, 2025
b8f9c94
Fix interface
scorbajio Mar 21, 2025
1400d45
Fix type issue
scorbajio Mar 21, 2025
f4bdd30
Access wrapped logger
scorbajio Mar 21, 2025
226f6b7
Add implementations and functions to logger interface
scorbajio Mar 21, 2025
bfe4fb6
Remove unused import
scorbajio Mar 21, 2025
70060ad
Access wrapped logger
scorbajio Mar 21, 2025
2d7d071
Fix lint issues
scorbajio Mar 21, 2025
2b7219a
Rename loggers
scorbajio Mar 21, 2025
9162e92
Access wrapped logger
scorbajio Mar 21, 2025
bfec030
Fix client best peer selection being based on a TD check
holgerd77 Mar 31, 2025
8e3c257
fix test
acolytec3 Mar 31, 2025
2231399
Merge remote-tracking branch 'origin/master' into fix-insane-client-p…
acolytec3 Mar 31, 2025
777cf22
Merge branch 'fix-insane-client-peer-td-check' of github.com:ethereum…
scorbajio Mar 31, 2025
efa0fa9
Merge branch 'master' of github.com:ethereumjs/ethereumjs-monorepo in…
scorbajio Apr 3, 2025
ff4c43d
Remove debug statement
scorbajio Apr 4, 2025
f094ccf
Remove duplicate winston level message
scorbajio Apr 4, 2025
6eab524
Add logtape interface implementation
scorbajio Apr 4, 2025
8c46e54
Merge branch 'master' of github.com:ethereumjs/ethereumjs-monorepo in…
scorbajio Apr 7, 2025
bb58468
Add logtape to package files
scorbajio Apr 7, 2025
3fab4ee
Make logger access use conditional check
scorbajio Apr 7, 2025
f3131a5
Get rid of getLogger init wrapper function
scorbajio Apr 7, 2025
8d54f27
Fix logLevel implementation in repl
scorbajio Apr 7, 2025
fc89555
Fix build issue
scorbajio Apr 7, 2025
ccd66cd
Fix lint errors
scorbajio Apr 7, 2025
4dfb0c6
Add logtape and logtapelogger to ignore list for spell check
scorbajio Apr 7, 2025
a0b9750
Merge branch 'master' of github.com:ethereumjs/ethereumjs-monorepo in…
scorbajio Apr 8, 2025
4dabaa1
Fix tests; add getLogger helper method
scorbajio Apr 8, 2025
86a9807
Fix test
scorbajio Apr 8, 2025
1039f93
Simplify getLevel implementation on classes
scorbajio Apr 8, 2025
67776a3
Add sanity check
scorbajio Apr 8, 2025
f73b225
Merge branch 'master' into client-logger-separation
scorbajio Apr 8, 2025
ba17e1e
Fix tests
scorbajio Apr 8, 2025
015d620
Merge branch 'client-logger-separation' of github.com:ethereumjs/ethe…
scorbajio Apr 8, 2025
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: 2 additions & 0 deletions config/cspell-ts.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
}
],
"words": [
"logtape",
"logtapelogger",
"bytelist",
"bytestring",
"binarytree",
Expand Down
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

114 changes: 92 additions & 22 deletions packages/client/bin/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,66 @@ import type * as http from 'http'
import type { Block, BlockBytes } from '@ethereumjs/block'
import type { ConsensusDict } from '@ethereumjs/blockchain'
import type { GenesisState } from '@ethereumjs/util'
import { getFileSink } from '@logtape/file'
import {
ansiColorFormatter,
configure,
getConsoleSink,
getLogger as getLogtapeLogger,
} from '@logtape/logtape'
import type { Logger as LogtapeLoggerType } from '@logtape/logtape'
import type { AbstractLevel } from 'abstract-level'
import type { Server as RPCServer } from 'jayson/promise/index.js'
import type { Config } from '../src/config.ts'
import type { Logger } from '../src/logging.ts'
import type { FullEthereumService } from '../src/service/index.ts'
import type { ClientOpts } from '../src/types.ts'
import type { ClientOpts, Logger } from '../src/types.ts'
import type { RPCArgs } from './startRPC.ts'

export class LogtapeLogger implements Logger {
public logger: LogtapeLoggerType

constructor(logger: LogtapeLoggerType) {
this.logger = logger

// Bind methods for logger instance
this.info = this.info.bind(this)
this.warn = this.warn.bind(this)
this.error = this.error.bind(this)
this.debug = this.debug.bind(this)
}

info(message: string, ...meta: any[]) {
this.logger?.info(`${message}`, ...meta)
}

warn(message: string, ...meta: any[]) {
this.logger?.warn(`${message}`, ...meta)
}

error(message: string, ...meta: any[]) {
this.logger?.error(`${message}`, ...meta)
}

debug(message: string, ...meta: any[]) {
this.logger?.debug(`${message}`, ...meta)
}

isInfoEnabled() {
const level = (this.logger as any).lowestLevel
return level === 'info' || level === 'debug'
}

configure(_: { [key: string]: any }) {
console.warn(
'Dynamic configuration is not supported in Logtapelogger. Please configure globally.',
)
}

getLevel() {
return (this.logger as any).lowestLevel
}
}

let logger: Logger

const args: ClientOpts = getArgs()
Expand Down Expand Up @@ -118,7 +170,7 @@ async function startBlock(client: EthereumClient) {
}
try {
await client.chain.resetCanonicalHead(startBlock)
client.config.logger.info(`Chain height reset to ${client.chain.headers.height}`)
client.config.logger?.info(`Chain height reset to ${client.chain.headers.height}`)
} catch (err: any) {
throw EthereumJSErrorWithoutCode(`Error setting back chain in startBlock: ${err}`)
}
Expand Down Expand Up @@ -150,7 +202,7 @@ async function startExecutionFrom(client: EthereumClient) {
try {
await client.chain.blockchain.setIteratorHead('vm', startExecutionParent.hash())
await client.chain.update(false)
client.config.logger.info(
client.config.logger?.info(
`vmHead set to ${client.chain.headers.height} for starting stateless execution at hardfork=${startExecutionHardfork}`,
)
} catch (err: any) {
Expand All @@ -162,7 +214,7 @@ async function startExecutionFrom(client: EthereumClient) {
try {
await client.chain.blockchain.setIteratorHead('vm', startExecutionParent.hash())
await client.chain.update(false)
client.config.logger.info(
client.config.logger?.info(
`vmHead set to ${client.chain.headers.height} for starting stateful execution at hardfork=${startExecutionHardfork}`,
)
} catch (err: any) {
Expand All @@ -186,7 +238,8 @@ async function startClient(
config: Config,
genesisMeta: { genesisState?: GenesisState; genesisStateRoot?: Uint8Array } = {},
) {
config.logger.info(`Data directory: ${config.datadir}`)
// TODO make sure all logger usage is preservable through newly created logger interface
config.logger?.info(`Data directory: ${config.datadir}`)

const dbs = initDBs(config)

Expand Down Expand Up @@ -243,13 +296,13 @@ async function startClient(
})
blocks.push(block)
buf = RLP.decode(buf.remainder, true)
config.logger.info(
config.logger?.info(
`Preloading block hash=${short(bytesToHex(block.header.hash()))} number=${
block.header.number
}`,
)
} catch (err: any) {
config.logger.info(
config.logger?.info(
`Encountered error while while preloading chain data error=${err.message}`,
)
break
Expand Down Expand Up @@ -310,28 +363,28 @@ const stopClient = async (
servers: (RPCServer | http.Server)[]
} | null>,
) => {
config.logger.info('Caught interrupt signal. Obtaining client handle for clean shutdown...')
config.logger.info('(This might take a little longer if client not yet fully started)')
config.logger?.info('Caught interrupt signal. Obtaining client handle for clean shutdown...')
config.logger?.info('(This might take a little longer if client not yet fully started)')
let timeoutHandle
if (clientStartPromise?.toString().includes('Promise') === true)
// Client hasn't finished starting up so setting timeout to terminate process if not already shutdown gracefully
timeoutHandle = setTimeout(() => {
config.logger.warn('Client has become unresponsive while starting up.')
config.logger.warn('Check logging output for potential errors. Exiting...')
config.logger?.warn('Client has become unresponsive while starting up.')
config.logger?.warn('Check logging output for potential errors. Exiting...')
process.exit(1)
}, 30000)
const clientHandle = await clientStartPromise
if (clientHandle !== null) {
config.logger.info('Shutting down the client and the servers...')
config.logger?.info('Shutting down the client and the servers...')
const { client, servers } = clientHandle
for (const s of servers) {
//@ts-expect-error jayson.Server type doesn't play well with ESM for some reason
s['http'] !== undefined ? (s as RPCServer).http().close() : (s as http.Server).close()
}
await client.stop()
config.logger.info('Exiting.')
config.logger?.info('Exiting.')
} else {
config.logger.info('Client did not start properly, exiting ...')
config.logger?.info('Client did not start properly, exiting ...')
}
clearTimeout(timeoutHandle)
process.exit()
Expand All @@ -346,10 +399,27 @@ async function run() {
return helpRPC()
}

// use Logtape logger with cli
const sinks: { [key: string]: any } = {
console: getConsoleSink({ formatter: ansiColorFormatter }),
}
if (typeof args.logFile === 'string') {
sinks.file = getFileSink(args.logFile)
}
await configure({
sinks,
loggers: [
{
category: 'ethjs',
lowestLevel: args.logLevel as any,
// Use all configured sink names.
sinks: Object.keys(sinks),
},
],
})
logger = new LogtapeLogger(getLogtapeLogger(['ethjs', 'client']))
const { config, customGenesisState, customGenesisStateRoot, metricsServer } =
await generateClientConfig(args)

logger = config.logger
await generateClientConfig({ ...args, logger })

// Do not wait for client to be fully started so that we can hookup SIGINT handling
// else a SIGINT before may kill the process in unclean manner
Expand All @@ -366,14 +436,14 @@ async function run() {
client.config.chainCommon.gteHardfork(Hardfork.Paris) &&
(args.rpcEngine === false || args.rpcEngine === undefined)
) {
config.logger.warn(`Engine RPC endpoint not activated on a post-Merge HF setup.`)
config.logger?.warn(`Engine RPC endpoint not activated on a post-Merge HF setup.`)
}
if (metricsServer !== undefined) servers.push(metricsServer)
config.superMsg('Client started successfully')
return { client, servers }
})
.catch((e) => {
config.logger.error('Error starting client', e)
config.logger?.error('Error starting client', e)
return null
})

Expand All @@ -388,8 +458,8 @@ async function run() {
process.on('uncaughtException', (err) => {
// Handles uncaught exceptions that are thrown in async events/functions and aren't caught in
// main client process
config.logger.error(`Uncaught error: ${err.message}`)
config.logger.error(err)
config.logger?.error(`Uncaught error: ${err.message}`)
config.logger?.error(err.stack ?? err.message)

void stopClient(config, clientStartPromise)
})
Expand Down
Loading
Loading