Skip to content
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

Allow JSON HTTP Request logging from the FileServer #82

Merged
merged 5 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
89 changes: 89 additions & 0 deletions forge/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,95 @@ const fp = require('fastify-plugin')
const path = require('path')
const YAML = require('yaml')

let config = {}

module.exports = {
init: (opts) => {
if (opts.config) {
// A custom config has been passed in. This means we're running
// programmatically rather than manually. At this stage, that
// means its our test framework.
process.env.NODE_ENV = 'development'
process.env.FLOWFORGE_HOME = process.cwd()
} else if (!process.env.FLOWFORGE_HOME) {
if (process.env.NODE_ENV === 'development') {
process.env.FLOWFORGE_HOME = path.resolve(__dirname, '../..')
} else {
process.env.FLOWFORGE_HOME = process.cwd()
if (fs.existsSync('/opt/flowforge-file-storage')) {
process.env.FLOWFORGE_HOME = '/opt/flowforge-file-storage'
} else {
process.env.FLOWFORGE_HOME = process.cwd()
}
}
}

let ffVersion
if (process.env.npm_package_version) {
ffVersion = process.env.npm_package_version
// npm start
} else {
// everything else
const { version } = require(path.join(module.parent.path, '..', 'package.json'))
ffVersion = version
}
try {
fs.statSync(path.join(__dirname, '..', '..', '.git'))
ffVersion += '-git'
} catch (err) {
// No git directory
}

if (opts.config !== undefined) {
// Programmatically provided config - eg tests
config = { ...opts.config }
} else {
let configFile = path.join(process.env.FLOWFORGE_HOME, '/etc/flowforge-storage.yml')
if (fs.existsSync(path.join(process.env.FLOWFORGE_HOME, '/etc/flowforge-storage.local.yml'))) {
configFile = path.join(process.env.FLOWFORGE_HOME, '/etc/flowforge-storage.local.yml')
}
try {
const configFileContent = fs.readFileSync(configFile, 'utf-8')
config = YAML.parse(configFileContent)
config.configFile = configFile
} catch (err) {
throw new Error(`Failed to read config file ${configFile}: ${err}`)
}
}

config.version = ffVersion
config.home = process.env.FLOWFORGE_HOME
config.port = process.env.PORT || config.port || 3001
config.host = config.host || 'localhost'

config.version = ffVersion
const defaultLogging = {
level: 'info',
http: 'warn',
pretty: process.env.NODE_ENV === 'development'
}
config.logging = { ...defaultLogging, ...config.logging }

return config
},
attach: fp(async function (app, opts, next) {
Object.freeze(config)
app.decorate('config', config)

if (process.env.NODE_ENV === 'development') {
app.log.info('Development mode')
}
app.log.info(`FlowFuse File Storage v${config.ffVersion}`)
app.log.info(`FlowFuse File Storage running with NodeJS ${process.version}`)
app.log.info(`FlowFuse File Storage HOME Directory: ${process.env.FLOWFORGE_HOME}`)
if (!opts.config) {
app.log.info(`Config File: ${config.configFile}`)
}

next()
})
}

module.exports = fp(async function (app, opts, next) {
if (!opts.config && process.env.FF_FS_TEST_CONFIG) {
opts.config = YAML.parse(process.env.FF_FS_TEST_CONFIG)
Expand Down
55 changes: 37 additions & 18 deletions forge/fileServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,48 @@ const routes = require('./routes')
const helmet = require('@fastify/helmet')

module.exports = async (options = {}) => {
let loggerLevel = 'info'
if (options.config?.logging?.level) {
loggerLevel = options.config.logging.level
const runtimeConfig = config.init(options)
const loggerConfig = {
formatters: {
level: (label) => {
return { level: label.toUpperCase() }
},
bindings: (bindings) => {
return { }
}
},
timestamp: require('pino').stdTimeFunctions.isoTime,
level: runtimeConfig.logging.level,
serializers: {
res (reply) {
return {
statusCode: reply.statusCode,
request: {
url: reply.request?.raw?.url,
method: reply.request?.method,
remoteAddress: reply.request?.ip,
remotePort: reply.request?.socket.remotePort
}
}
}
}
}
if (runtimeConfig.logging.pretty !== false) {
loggerConfig.transport = {
target: 'pino-pretty',
options: {
translateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss.l'Z'",
ignore: 'pid,hostname',
singleLine: true
}
}
}

const server = fastify({
bodyLimit: 10 * 1024 * 1024, // Limit set to 10MB,
maxParamLength: 500,
trustProxy: true,
logger: {
transport: {
target: 'pino-pretty',
options: {
translateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss.l'Z'",
ignore: 'pid,hostname',
singleLine: true
}
},
level: loggerLevel
}
logger: loggerConfig
})

server.addHook('onError', async (request, reply, error) => {
Expand All @@ -35,10 +57,7 @@ module.exports = async (options = {}) => {

try {
// Config
await server.register(config, options)
if (server.config.logging?.level) {
server.log.level = server.config.logging.level
}
await server.register(config.attach, options)

// // Setup DB
// await server.register(db, {})
Expand Down
29 changes: 15 additions & 14 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"fastify-plugin": "^4.5.1",
"got": "^11.8.6",
"pg": "^8.11.2",
"pino": "^8.15.1",
"pino-pretty": "^10.2.0",
"semver": "^7.5.4",
"sequelize": "^6.33.0",
Expand Down