mirror of
https://github.com/standardnotes/server
synced 2026-01-16 20:04:32 -05:00
feat(home-server): add custom home server logs (#619)
* feat(home-server): add custom home server logs * fix(home-server): asyn state of logs function
This commit is contained in:
6
.pnp.cjs
generated
6
.pnp.cjs
generated
@@ -4751,6 +4751,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/jsonwebtoken", "npm:9.0.2"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@types/prettyjson", "npm:0.0.30"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
@@ -4811,6 +4812,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/ioredis", "npm:5.0.0"],\
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@types/otplib", "npm:10.0.0"],\
|
||||
["@types/prettyjson", "npm:0.0.30"],\
|
||||
["@types/ua-parser-js", "npm:0.7.36"],\
|
||||
@@ -4874,6 +4876,7 @@ const RAW_RUNTIME_STATE =
|
||||
"packageDependencies": [\
|
||||
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@types/uuid", "npm:8.3.4"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
@@ -5019,6 +5022,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/jsonwebtoken", "npm:9.0.2"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@types/prettyjson", "npm:0.0.30"],\
|
||||
["@types/uuid", "npm:8.3.4"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
@@ -5153,6 +5157,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/express", "npm:4.17.17"],\
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.59.2"],\
|
||||
["cors", "npm:2.8.5"],\
|
||||
@@ -5338,6 +5343,7 @@ const RAW_RUNTIME_STATE =
|
||||
["@types/jest", "npm:29.5.1"],\
|
||||
["@types/jsonwebtoken", "npm:9.0.2"],\
|
||||
["@types/newrelic", "npm:9.13.0"],\
|
||||
["@types/node", "npm:20.2.5"],\
|
||||
["@types/prettyjson", "npm:0.0.30"],\
|
||||
["@types/ua-parser-js", "npm:0.7.36"],\
|
||||
["@types/uuid", "npm:8.3.4"],\
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.2",
|
||||
|
||||
@@ -21,12 +21,13 @@ import { EndpointResolverInterface } from '../Service/Resolver/EndpointResolverI
|
||||
import { EndpointResolver } from '../Service/Resolver/EndpointResolver'
|
||||
import { RequiredCrossServiceTokenMiddleware } from '../Controller/RequiredCrossServiceTokenMiddleware'
|
||||
import { OptionalCrossServiceTokenMiddleware } from '../Controller/OptionalCrossServiceTokenMiddleware'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
async load(serviceContainer?: ServiceContainerInterface): Promise<Container> {
|
||||
async load(configuration?: { serviceContainer?: ServiceContainerInterface; logger?: Transform }): Promise<Container> {
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
@@ -40,13 +41,17 @@ export class ContainerConfigLoader {
|
||||
winstonFormatters.push(newrelicWinstonFormatter())
|
||||
}
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'api-gateway' },
|
||||
})
|
||||
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
|
||||
if (configuration?.logger) {
|
||||
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(configuration.logger as winston.Logger)
|
||||
} else {
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'api-gateway' },
|
||||
})
|
||||
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
|
||||
}
|
||||
|
||||
if (!isConfiguredForHomeServer) {
|
||||
const redisUrl = env.get('REDIS_URL')
|
||||
@@ -91,12 +96,14 @@ export class ContainerConfigLoader {
|
||||
|
||||
// Services
|
||||
if (isConfiguredForHomeServer) {
|
||||
if (!serviceContainer) {
|
||||
if (!configuration?.serviceContainer) {
|
||||
throw new Error('Service container is required when configured for home server')
|
||||
}
|
||||
container
|
||||
.bind<ServiceProxyInterface>(TYPES.ServiceProxy)
|
||||
.toConstantValue(new DirectCallServiceProxy(serviceContainer, container.get(TYPES.FILES_SERVER_URL)))
|
||||
.toConstantValue(
|
||||
new DirectCallServiceProxy(configuration.serviceContainer, container.get(TYPES.FILES_SERVER_URL)),
|
||||
)
|
||||
} else {
|
||||
container.bind<ServiceProxyInterface>(TYPES.ServiceProxy).to(HttpServiceProxy)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
import { ServiceContainerInterface, ServiceIdentifier, ServiceInterface } from '@standardnotes/domain-core'
|
||||
|
||||
import { ContainerConfigLoader } from './Container'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
export class Service implements ServiceInterface {
|
||||
private logger: Transform | undefined
|
||||
|
||||
constructor(private serviceContainer: ServiceContainerInterface) {
|
||||
this.serviceContainer.register(this.getId(), this)
|
||||
}
|
||||
|
||||
setLogger(logger: Transform): void {
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
async handleRequest(_request: never, _response: never, _endpointOrMethodIdentifier: string): Promise<unknown> {
|
||||
throw new Error('Requests are handled via inversify-express at ApiGateway level')
|
||||
}
|
||||
@@ -14,7 +21,10 @@ export class Service implements ServiceInterface {
|
||||
async getContainer(): Promise<unknown> {
|
||||
const config = new ContainerConfigLoader()
|
||||
|
||||
return config.load(this.serviceContainer)
|
||||
return config.load({
|
||||
serviceContainer: this.serviceContainer,
|
||||
logger: this.logger,
|
||||
})
|
||||
}
|
||||
|
||||
getId(): ServiceIdentifier {
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export * from './Service'
|
||||
export * from './Types'
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
"@types/ioredis": "^5.0.0",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/otplib": "^10.0.0",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
|
||||
@@ -250,6 +250,7 @@ import { HomeServerUsersController } from '../Infra/InversifyExpressUtils/HomeSe
|
||||
import { HomeServerValetTokenController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerValetTokenController'
|
||||
import { HomeServerWebSocketsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerWebSocketsController'
|
||||
import { HomeServerSessionsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerSessionsController'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
@@ -258,6 +259,7 @@ export class ContainerConfigLoader {
|
||||
async load(configuration?: {
|
||||
controllerConatiner?: ControllerContainerInterface
|
||||
directCallDomainEventPublisher?: DirectCallDomainEventPublisher
|
||||
logger?: Transform
|
||||
}): Promise<Container> {
|
||||
const directCallDomainEventPublisher =
|
||||
configuration?.directCallDomainEventPublisher ?? new DirectCallDomainEventPublisher()
|
||||
@@ -290,13 +292,17 @@ export class ContainerConfigLoader {
|
||||
winstonFormatters.push(newrelicWinstonFormatter())
|
||||
}
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'auth' },
|
||||
})
|
||||
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
|
||||
if (configuration?.logger) {
|
||||
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(configuration.logger as winston.Logger)
|
||||
} else {
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'auth' },
|
||||
})
|
||||
container.bind<winston.Logger>(TYPES.Auth_Logger).toConstantValue(logger)
|
||||
}
|
||||
|
||||
container.bind<TimerInterface>(TYPES.Auth_Timer).toConstantValue(new Timer())
|
||||
|
||||
|
||||
@@ -7,8 +7,11 @@ import {
|
||||
|
||||
import { ContainerConfigLoader } from './Container'
|
||||
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
export class Service implements ServiceInterface {
|
||||
private logger: Transform | undefined
|
||||
|
||||
constructor(
|
||||
private serviceContainer: ServiceContainerInterface,
|
||||
private controllerContainer: ControllerContainerInterface,
|
||||
@@ -17,6 +20,10 @@ export class Service implements ServiceInterface {
|
||||
this.serviceContainer.register(this.getId(), this)
|
||||
}
|
||||
|
||||
setLogger(logger: Transform): void {
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
async handleRequest(request: never, response: never, endpointOrMethodIdentifier: string): Promise<unknown> {
|
||||
const method = this.controllerContainer.get(endpointOrMethodIdentifier)
|
||||
|
||||
@@ -33,6 +40,7 @@ export class Service implements ServiceInterface {
|
||||
return config.load({
|
||||
controllerConatiner: this.controllerContainer,
|
||||
directCallDomainEventPublisher: this.directCallDomainEventPublisher,
|
||||
logger: this.logger,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/uuid": "^8.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.2",
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { ServiceIdentifier } from './ServiceIdentifier'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
export interface ServiceInterface {
|
||||
getContainer(): Promise<unknown>
|
||||
setLogger(logger: Transform): void
|
||||
getId(): ServiceIdentifier
|
||||
handleRequest(request: never, response: never, endpointOrMethodIdentifier: string): Promise<unknown>
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@types/uuid": "^8.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
|
||||
@@ -47,9 +47,13 @@ import { MarkFilesToBeRemoved } from '../Domain/UseCase/MarkFilesToBeRemoved/Mar
|
||||
import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
|
||||
import { SharedSubscriptionInvitationCanceledEventHandler } from '../Domain/Handler/SharedSubscriptionInvitationCanceledEventHandler'
|
||||
import { InMemoryUploadRepository } from '../Infra/InMemory/InMemoryUploadRepository'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
async load(configuration?: { directCallDomainEventPublisher?: DirectCallDomainEventPublisher }): Promise<Container> {
|
||||
async load(configuration?: {
|
||||
directCallDomainEventPublisher?: DirectCallDomainEventPublisher
|
||||
logger?: Transform
|
||||
}): Promise<Container> {
|
||||
const directCallDomainEventPublisher =
|
||||
configuration?.directCallDomainEventPublisher ?? new DirectCallDomainEventPublisher()
|
||||
|
||||
@@ -60,8 +64,11 @@ export class ContainerConfigLoader {
|
||||
|
||||
const isConfiguredForHomeServer = env.get('CACHE_TYPE') === 'memory'
|
||||
|
||||
const logger = this.createLogger({ env })
|
||||
container.bind<winston.Logger>(TYPES.Files_Logger).toConstantValue(logger)
|
||||
if (configuration?.logger) {
|
||||
container.bind<winston.Logger>(TYPES.Files_Logger).toConstantValue(configuration.logger as winston.Logger)
|
||||
} else {
|
||||
container.bind<winston.Logger>(TYPES.Files_Logger).toConstantValue(this.createLogger({ env }))
|
||||
}
|
||||
|
||||
container.bind<TimerInterface>(TYPES.Files_Timer).toConstantValue(new Timer())
|
||||
|
||||
|
||||
@@ -2,8 +2,11 @@ import { ServiceContainerInterface, ServiceIdentifier, ServiceInterface } from '
|
||||
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra'
|
||||
|
||||
import { ContainerConfigLoader } from './Container'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
export class Service implements ServiceInterface {
|
||||
private logger: Transform | undefined
|
||||
|
||||
constructor(
|
||||
private serviceContainer: ServiceContainerInterface,
|
||||
private directCallDomainEventPublisher: DirectCallDomainEventPublisher,
|
||||
@@ -11,6 +14,10 @@ export class Service implements ServiceInterface {
|
||||
this.serviceContainer.register(this.getId(), this)
|
||||
}
|
||||
|
||||
setLogger(logger: Transform): void {
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
async handleRequest(_request: never, _response: never, _endpointOrMethodIdentifier: string): Promise<unknown> {
|
||||
throw new Error('Requests are handled via inversify-express at ApiGateway level')
|
||||
}
|
||||
@@ -20,6 +27,7 @@ export class Service implements ServiceInterface {
|
||||
|
||||
return config.load({
|
||||
directCallDomainEventPublisher: this.directCallDomainEventPublisher,
|
||||
logger: this.logger,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { HomeServer } from '../src/Bootstrap/HomeServer'
|
||||
import { HomeServer } from '../src/Server/HomeServer'
|
||||
|
||||
const homeServer = new HomeServer()
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './HomeServer'
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { ControllerContainer, ServiceContainer } from '@standardnotes/domain-core'
|
||||
import { Service as ApiGatewayService, TYPES as ApiGatewayTYPES } from '@standardnotes/api-gateway'
|
||||
import { Service as ApiGatewayService } from '@standardnotes/api-gateway'
|
||||
import { Service as FilesService } from '@standardnotes/files-server'
|
||||
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra'
|
||||
import { Service as AuthService } from '@standardnotes/auth-server'
|
||||
@@ -11,24 +11,39 @@ import { Container } from 'inversify'
|
||||
import { InversifyExpressServer } from 'inversify-express-utils'
|
||||
import helmet from 'helmet'
|
||||
import * as cors from 'cors'
|
||||
import * as http from 'http'
|
||||
import { text, json, Request, Response, NextFunction } from 'express'
|
||||
import * as winston from 'winston'
|
||||
import { PassThrough } from 'stream'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const robots = require('express-robots-txt')
|
||||
|
||||
import { Env } from './Env'
|
||||
import { Env } from '../Bootstrap/Env'
|
||||
import { HomeServerInterface } from './HomeServerInterface'
|
||||
|
||||
export class HomeServer implements HomeServerInterface {
|
||||
private serverInstance: http.Server | undefined
|
||||
|
||||
export class HomeServer {
|
||||
async start(): Promise<void> {
|
||||
const controllerContainer = new ControllerContainer()
|
||||
const serviceContainer = new ServiceContainer()
|
||||
const directCallDomainEventPublisher = new DirectCallDomainEventPublisher()
|
||||
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
this.configureLoggers(env)
|
||||
|
||||
const apiGatewayService = new ApiGatewayService(serviceContainer)
|
||||
apiGatewayService.setLogger(winston.loggers.get('api-gateway'))
|
||||
const authService = new AuthService(serviceContainer, controllerContainer, directCallDomainEventPublisher)
|
||||
authService.setLogger(winston.loggers.get('auth-server'))
|
||||
const syncingService = new SyncingService(serviceContainer, controllerContainer, directCallDomainEventPublisher)
|
||||
syncingService.setLogger(winston.loggers.get('syncing-server'))
|
||||
const revisionsService = new RevisionsService(serviceContainer, controllerContainer, directCallDomainEventPublisher)
|
||||
revisionsService.setLogger(winston.loggers.get('revisions-server'))
|
||||
const filesService = new FilesService(serviceContainer, directCallDomainEventPublisher)
|
||||
filesService.setLogger(winston.loggers.get('files-server'))
|
||||
|
||||
const container = Container.merge(
|
||||
(await apiGatewayService.getContainer()) as Container,
|
||||
@@ -38,9 +53,6 @@ export class HomeServer {
|
||||
(await filesService.getContainer()) as Container,
|
||||
)
|
||||
|
||||
const env: Env = new Env()
|
||||
env.load()
|
||||
|
||||
const server = new InversifyExpressServer(container)
|
||||
|
||||
server.setConfig((app) => {
|
||||
@@ -81,7 +93,7 @@ export class HomeServer {
|
||||
)
|
||||
})
|
||||
|
||||
const logger: winston.Logger = container.get(ApiGatewayTYPES.Logger)
|
||||
const logger: winston.Logger = winston.loggers.get('home-server')
|
||||
|
||||
server.setErrorConfig((app) => {
|
||||
app.use((error: Record<string, unknown>, _request: Request, response: Response, _next: NextFunction) => {
|
||||
@@ -96,10 +108,57 @@ export class HomeServer {
|
||||
})
|
||||
})
|
||||
|
||||
const serverInstance = server.build()
|
||||
|
||||
serverInstance.listen(env.get('PORT', true) ? +env.get('PORT', true) : 3000)
|
||||
this.serverInstance = server.build().listen(env.get('PORT', true) ? +env.get('PORT', true) : 3000)
|
||||
|
||||
logger.info(`Server started on port ${process.env.PORT}`)
|
||||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
if (this.serverInstance) {
|
||||
this.serverInstance.close()
|
||||
}
|
||||
}
|
||||
|
||||
async restart(): Promise<void> {
|
||||
await this.stop()
|
||||
await this.start()
|
||||
}
|
||||
|
||||
async isRunning(): Promise<boolean> {
|
||||
if (!this.serverInstance) {
|
||||
return false
|
||||
}
|
||||
|
||||
return this.serverInstance.address() !== null
|
||||
}
|
||||
|
||||
logs(): NodeJS.ReadableStream {
|
||||
const passThroughStream = new PassThrough()
|
||||
|
||||
for (const logger of winston.loggers.loggers.values()) {
|
||||
logger.stream({ start: -1 }).pipe(passThroughStream, { end: false })
|
||||
}
|
||||
|
||||
return passThroughStream
|
||||
}
|
||||
|
||||
private configureLoggers(env: Env): void {
|
||||
const winstonFormatters = [winston.format.splat(), winston.format.json()]
|
||||
|
||||
for (const loggerName of [
|
||||
'auth-server',
|
||||
'syncing-server',
|
||||
'revisions-server',
|
||||
'files-server',
|
||||
'api-gateway',
|
||||
'home-server',
|
||||
]) {
|
||||
winston.loggers.add(loggerName, {
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: loggerName },
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
7
packages/home-server/src/Server/HomeServerInterface.ts
Normal file
7
packages/home-server/src/Server/HomeServerInterface.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface HomeServerInterface {
|
||||
start(): Promise<void>
|
||||
stop(): Promise<void>
|
||||
restart(): Promise<void>
|
||||
isRunning(): Promise<boolean>
|
||||
logs(): NodeJS.ReadableStream
|
||||
}
|
||||
2
packages/home-server/src/Server/index.ts
Normal file
2
packages/home-server/src/Server/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './HomeServer'
|
||||
export * from './HomeServerInterface'
|
||||
@@ -1 +1 @@
|
||||
export * from './Bootstrap'
|
||||
export * from './Server'
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
"@types/node": "^20.2.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.2",
|
||||
"eslint": "^8.39.0",
|
||||
|
||||
@@ -46,6 +46,7 @@ import { FSDumpRepository } from '../Infra/FS/FSDumpRepository'
|
||||
import { S3DumpRepository } from '../Infra/S3/S3ItemDumpRepository'
|
||||
import { RevisionItemStringMapper } from '../Mapping/RevisionItemStringMapper'
|
||||
import { HomeServerRevisionsController } from '../Infra/InversifyExpress/HomeServer/HomeServerRevisionsController'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
@@ -54,6 +55,7 @@ export class ContainerConfigLoader {
|
||||
async load(configuration?: {
|
||||
controllerConatiner?: ControllerContainerInterface
|
||||
directCallDomainEventPublisher?: DirectCallDomainEventPublisher
|
||||
logger?: Transform
|
||||
}): Promise<Container> {
|
||||
const directCallDomainEventPublisher =
|
||||
configuration?.directCallDomainEventPublisher ?? new DirectCallDomainEventPublisher()
|
||||
@@ -71,24 +73,28 @@ export class ContainerConfigLoader {
|
||||
|
||||
container.bind<Env>(TYPES.Revisions_Env).toConstantValue(env)
|
||||
|
||||
container.bind<winston.Logger>(TYPES.Revisions_Logger).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Revisions_Env)
|
||||
if (configuration?.logger) {
|
||||
container.bind<winston.Logger>(TYPES.Revisions_Logger).toConstantValue(configuration.logger as winston.Logger)
|
||||
} else {
|
||||
container.bind<winston.Logger>(TYPES.Revisions_Logger).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Revisions_Env)
|
||||
|
||||
const newrelicWinstonFormatter = newrelicFormatter(winston)
|
||||
const winstonFormatters = [winston.format.splat(), winston.format.json()]
|
||||
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
|
||||
winstonFormatters.push(newrelicWinstonFormatter())
|
||||
}
|
||||
const newrelicWinstonFormatter = newrelicFormatter(winston)
|
||||
const winstonFormatters = [winston.format.splat(), winston.format.json()]
|
||||
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
|
||||
winstonFormatters.push(newrelicWinstonFormatter())
|
||||
}
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'revisions' },
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'revisions' },
|
||||
})
|
||||
|
||||
return logger
|
||||
})
|
||||
|
||||
return logger
|
||||
})
|
||||
}
|
||||
|
||||
container.bind(TYPES.Revisions_NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
|
||||
container.bind(TYPES.Revisions_VERSION).toConstantValue(env.get('VERSION'))
|
||||
|
||||
@@ -7,8 +7,11 @@ import {
|
||||
|
||||
import { ContainerConfigLoader } from './Container'
|
||||
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
export class Service implements ServiceInterface {
|
||||
private logger: Transform | undefined
|
||||
|
||||
constructor(
|
||||
private serviceContainer: ServiceContainerInterface,
|
||||
private controllerContainer: ControllerContainerInterface,
|
||||
@@ -17,6 +20,10 @@ export class Service implements ServiceInterface {
|
||||
this.serviceContainer.register(this.getId(), this)
|
||||
}
|
||||
|
||||
setLogger(logger: Transform): void {
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
async handleRequest(request: never, response: never, endpointOrMethodIdentifier: string): Promise<unknown> {
|
||||
const method = this.controllerContainer.get(endpointOrMethodIdentifier)
|
||||
|
||||
@@ -33,6 +40,7 @@ export class Service implements ServiceInterface {
|
||||
return config.load({
|
||||
controllerConatiner: this.controllerContainer,
|
||||
directCallDomainEventPublisher: this.directCallDomainEventPublisher,
|
||||
logger: this.logger,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/jsonwebtoken": "^9.0.1",
|
||||
"@types/newrelic": "^9.13.0",
|
||||
"@types/node": "^20.2.5",
|
||||
"@types/prettyjson": "^0.0.30",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
"@types/uuid": "^8.3.0",
|
||||
|
||||
@@ -72,6 +72,7 @@ import { AuthHttpService } from '../Infra/HTTP/AuthHttpService'
|
||||
import { S3ItemBackupService } from '../Infra/S3/S3ItemBackupService'
|
||||
import { ControllerContainer, ControllerContainerInterface } from '@standardnotes/domain-core'
|
||||
import { HomeServerItemsController } from '../Infra/InversifyExpressUtils/HomeServer/HomeServerItemsController'
|
||||
import { Transform } from 'stream'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
|
||||
@@ -83,6 +84,7 @@ export class ContainerConfigLoader {
|
||||
async load(configuration?: {
|
||||
controllerConatiner?: ControllerContainerInterface
|
||||
directCallDomainEventPublisher?: DirectCallDomainEventPublisher
|
||||
logger?: Transform
|
||||
}): Promise<Container> {
|
||||
const directCallDomainEventPublisher =
|
||||
configuration?.directCallDomainEventPublisher ?? new DirectCallDomainEventPublisher()
|
||||
@@ -100,24 +102,28 @@ export class ContainerConfigLoader {
|
||||
|
||||
container.bind<Env>(TYPES.Sync_Env).toConstantValue(env)
|
||||
|
||||
container.bind<winston.Logger>(TYPES.Sync_Logger).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
if (configuration?.logger) {
|
||||
container.bind<winston.Logger>(TYPES.Sync_Logger).toConstantValue(configuration.logger as winston.Logger)
|
||||
} else {
|
||||
container.bind<winston.Logger>(TYPES.Sync_Logger).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
|
||||
const newrelicWinstonFormatter = newrelicFormatter(winston)
|
||||
const winstonFormatters = [winston.format.splat(), winston.format.json()]
|
||||
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
|
||||
winstonFormatters.push(newrelicWinstonFormatter())
|
||||
}
|
||||
const newrelicWinstonFormatter = newrelicFormatter(winston)
|
||||
const winstonFormatters = [winston.format.splat(), winston.format.json()]
|
||||
if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
|
||||
winstonFormatters.push(newrelicWinstonFormatter())
|
||||
}
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'syncing-server' },
|
||||
const logger = winston.createLogger({
|
||||
level: env.get('LOG_LEVEL') || 'info',
|
||||
format: winston.format.combine(...winstonFormatters),
|
||||
transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL') || 'info' })],
|
||||
defaultMeta: { service: 'syncing-server' },
|
||||
})
|
||||
|
||||
return logger
|
||||
})
|
||||
|
||||
return logger
|
||||
})
|
||||
}
|
||||
|
||||
if (isConfiguredForHomeServer) {
|
||||
container
|
||||
|
||||
@@ -7,8 +7,11 @@ import {
|
||||
|
||||
import { ContainerConfigLoader } from './Container'
|
||||
import { DirectCallDomainEventPublisher } from '@standardnotes/domain-events-infra'
|
||||
import { Transform } from 'stream'
|
||||
|
||||
export class Service implements ServiceInterface {
|
||||
private logger: Transform | undefined
|
||||
|
||||
constructor(
|
||||
private serviceContainer: ServiceContainerInterface,
|
||||
private controllerContainer: ControllerContainerInterface,
|
||||
@@ -17,6 +20,10 @@ export class Service implements ServiceInterface {
|
||||
this.serviceContainer.register(this.getId(), this)
|
||||
}
|
||||
|
||||
setLogger(logger: Transform): void {
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
async handleRequest(request: never, response: never, endpointOrMethodIdentifier: string): Promise<unknown> {
|
||||
const method = this.controllerContainer.get(endpointOrMethodIdentifier)
|
||||
|
||||
@@ -33,6 +40,7 @@ export class Service implements ServiceInterface {
|
||||
return config.load({
|
||||
controllerConatiner: this.controllerContainer,
|
||||
directCallDomainEventPublisher: this.directCallDomainEventPublisher,
|
||||
logger: this.logger,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -4281,6 +4281,7 @@ __metadata:
|
||||
"@types/jest": "npm:^29.5.1"
|
||||
"@types/jsonwebtoken": "npm:^9.0.1"
|
||||
"@types/newrelic": "npm:^9.13.0"
|
||||
"@types/node": "npm:^20.2.5"
|
||||
"@types/prettyjson": "npm:^0.0.30"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^5.59.2"
|
||||
"@typescript-eslint/parser": "npm:^5.59.2"
|
||||
@@ -4355,6 +4356,7 @@ __metadata:
|
||||
"@types/ioredis": "npm:^5.0.0"
|
||||
"@types/jest": "npm:^29.5.1"
|
||||
"@types/newrelic": "npm:^9.13.0"
|
||||
"@types/node": "npm:^20.2.5"
|
||||
"@types/otplib": "npm:^10.0.0"
|
||||
"@types/prettyjson": "npm:^0.0.30"
|
||||
"@types/ua-parser-js": "npm:^0.7.36"
|
||||
@@ -4414,6 +4416,7 @@ __metadata:
|
||||
resolution: "@standardnotes/domain-core@workspace:packages/domain-core"
|
||||
dependencies:
|
||||
"@types/jest": "npm:^29.5.1"
|
||||
"@types/node": "npm:^20.2.5"
|
||||
"@types/uuid": "npm:^8.3.0"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^5.59.2"
|
||||
"@typescript-eslint/parser": "npm:^5.59.2"
|
||||
@@ -4549,6 +4552,7 @@ __metadata:
|
||||
"@types/jest": "npm:^29.5.1"
|
||||
"@types/jsonwebtoken": "npm:^9.0.1"
|
||||
"@types/newrelic": "npm:^9.13.0"
|
||||
"@types/node": "npm:^20.2.5"
|
||||
"@types/prettyjson": "npm:^0.0.30"
|
||||
"@types/uuid": "npm:^8.3.0"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^5.59.2"
|
||||
@@ -4675,6 +4679,7 @@ __metadata:
|
||||
"@types/express": "npm:^4.17.14"
|
||||
"@types/jest": "npm:^29.5.1"
|
||||
"@types/newrelic": "npm:^9.13.0"
|
||||
"@types/node": "npm:^20.2.5"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^5.59.2"
|
||||
"@typescript-eslint/parser": "npm:^5.59.2"
|
||||
cors: "npm:2.8.5"
|
||||
@@ -4850,6 +4855,7 @@ __metadata:
|
||||
"@types/jest": "npm:^29.5.1"
|
||||
"@types/jsonwebtoken": "npm:^9.0.1"
|
||||
"@types/newrelic": "npm:^9.13.0"
|
||||
"@types/node": "npm:^20.2.5"
|
||||
"@types/prettyjson": "npm:^0.0.30"
|
||||
"@types/ua-parser-js": "npm:^0.7.36"
|
||||
"@types/uuid": "npm:^8.3.0"
|
||||
@@ -5343,7 +5349,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^20.2.0":
|
||||
"@types/node@npm:^20.2.0, @types/node@npm:^20.2.5":
|
||||
version: 20.2.5
|
||||
resolution: "@types/node@npm:20.2.5"
|
||||
checksum: 55e4f8d08e3c225e48e012e04458d6c1db5af6e4991e3abb003b82d3f10018a14742c0512b27991cb02e54768be560ea1fe4c17208e04273247132c9eb07499a
|
||||
|
||||
Reference in New Issue
Block a user