-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathlog-generator.js
executable file
·175 lines (152 loc) · 4.53 KB
/
log-generator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/env node
/*
* Copyright 2022 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
'use strict'
process.env.NEW_RELIC_NO_CONFIG_FILE = true
process.env.NEW_RELIC_APP_NAME = 'log-generator'
// process.env.NEW_RELIC_LICENSE_KEY = <your-license-key>
process.env.NEW_RELIC_HOST = 'staging-collector.newrelic.com'
process.env.NEW_RELIC_LOG_LEVEL = 'info'
// set the next env var to false to disable all application logging features
process.env.NEW_RELIC_APPLICATION_LOGGING_ENABLED = true
process.env.NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED = true
process.env.NEW_RELIC_APPLICATION_LOGGING_METRICS_ENABLED = true
process.env.NEW_RELIC_APPLICATION_LOGGING_FORWARDING_MAX_SAMPLES_STORED = 10000
process.env.NEW_RELIC_APPLICATION_LOGGING_LOCAL_DECORATING_ENABLED = false
const newrelic = require('newrelic')
// we can't put a listener for 'errored'
// because this happens before `const newrelic = require('newrelic')`
// wrap in next tick so we can error from agent before exiting process
process.nextTick(() => {
if (newrelic.agent._state === 'errored') {
process.exit(1)
}
})
const yargs = require('yargs')
const { hideBin } = require('yargs/helpers')
const faker = require('faker')
function getArgs() {
return yargs(hideBin(process.argv))
.scriptName(process.env.NEW_RELIC_APP_NAME)
.usage(
'Usage: $0 OPTIONS\n\nstarts a process that will generate logs with either winston or pino'
)
.option('logtype', {
alias: 'l',
describe: 'which logger to use',
choices: ['winston', 'pino'],
default: 'winston',
type: 'string'
})
.option('interval', {
alias: 'i',
describe: 'interval in milliseconds to wait between each round of log messages',
default: 200,
type: 'number'
})
.option('count', {
alias: 'c',
describe: 'number of log messages to produce at each round',
default: 1,
type: 'number'
})
.option('size', {
alias: 's',
describe: 'size of each log message, in characters',
default: 128,
type: 'number'
})
.option('duration', {
alias: 'd',
describe: 'how many seconds to run for (use 0 seconds to run forever)',
default: 0,
type: 'number'
})
.help().argv
}
// https://stackoverflow.com/a/55671924
function weightedRandom(options) {
let i
const weights = []
for (i = 0; i < options.length; i++) {
weights[i] = options[i].weight + (weights[i - 1] || 0)
}
const random = Math.random() * weights[weights.length - 1]
for (i = 0; i < weights.length; i++) {
if (weights[i] > random) {
break
}
}
return options[i].item
}
function getRandomLogLevel() {
// Winston and pino define different log levels, but at least have
// these in common.
const logLevels = [
{ item: 'error', weight: 1 },
{ item: 'warn', weight: 4 },
{ item: 'info', weight: 16 },
{ item: 'debug', weight: 64 }
]
return weightedRandom(logLevels)
}
function getLogger(logtype) {
let logger
if (logtype === 'winston') {
const winston = require('winston')
const { createLogger, format, transports } = winston
logger = createLogger({
level: 'debug',
format: format.combine(
format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
format.errors({ stack: true }),
format.splat(),
format.json()
),
defaultMeta: { service: process.env.NEW_RELIC_APP_NAME },
transports: [new transports.Console()]
})
} else {
const pino = require('pino')
logger = pino({ level: 'debug' })
}
return logger
}
function runOneBatchOfLogs(logger, interval, count, size) {
return new Promise((resolve) => {
setTimeout(() => {
for (let i = 0; i < count; i++) {
logger[getRandomLogLevel()](faker.random.alphaNumeric(size))
}
resolve()
}, interval)
})
}
function run(logger, interval, count, size) {
newrelic
.startBackgroundTransaction('loggingTransaction', () => {
return runOneBatchOfLogs(logger, interval, count, size)
})
.then(() => {
run(logger, interval, count, size)
})
}
function shutdown() {
newrelic.shutdown({ collectPendingData: true }, () => {
process.exit(0) // eslint-disable-line no-process-exit
})
}
function setUp(duration) {
if (duration > 0) {
setTimeout(shutdown, duration * 1000)
}
process.on('SIGINT', shutdown)
}
const { logtype, interval, count, size, duration } = getArgs()
const logger = getLogger(logtype)
setUp(duration)
run(logger, interval, count, size)