Skip to content

Commit 4b19320

Browse files
logs (#34)
* logs improvements * fix tests * bump * bump Co-authored-by: Denis <[email protected]>
1 parent 4ba346b commit 4b19320

File tree

10 files changed

+308
-68
lines changed

10 files changed

+308
-68
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ module.exports = {
115115
},
116116
{
117117
'selector': 'objectLiteralProperty',
118-
'format': ['camelCase', 'UPPER_CASE'],
118+
'format': ['camelCase', 'UPPER_CASE', 'PascalCase'],
119119
'leadingUnderscore': 'allow',
120120
},
121121
{

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
"node": "16.14.2"
2525
},
2626
"dependencies": {
27-
"eventsource": "^2.0.1"
27+
"chalk": "4.1.2",
28+
"eventsource": "^2.0.1",
29+
"winston": "^3.7.2"
2830
},
2931
"devDependencies": {
3032
"@types/jest": "^27.5.1",

service.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
name: csdp-report-image
2-
version: 0.0.41
2+
version: 0.0.42

src/__tests__/request-builder.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { buildUrlHeaders } from '../request-builder'
1+
import { buildUrlHeaders } from '../utils'
22

33

44
describe('request builder test', () => {

src/logger.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import winston from 'winston'
2+
import chalk from 'chalk'
3+
4+
const format = winston.format
5+
const paint = (kind, message) => {
6+
const painter = {
7+
error: chalk.red,
8+
warn: chalk.yellow,
9+
workflowLog: chalk.blue
10+
}[kind]
11+
12+
if (painter) {
13+
return painter(message)
14+
}
15+
return message
16+
}
17+
18+
19+
export const logger = winston.createLogger({
20+
format: format.printf((info) => {
21+
return paint(info.level, `${info.message}`)
22+
}),
23+
transports: [ new winston.transports.Console() ],
24+
})
25+
26+
export const workflowLogger = winston.createLogger({
27+
format: format.printf((info) => {
28+
let logMessage = `${info.message}`
29+
if (info.pod) {
30+
logMessage = `[${info.pod}] ${logMessage}`
31+
}
32+
return paint('workflowLog', logMessage)
33+
}),
34+
transports: [ new winston.transports.Console() ],
35+
})

src/main.ts

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,85 @@
11
import EventSource from 'eventsource'
22

33
import { validate } from './validate'
4-
import { buildUrlHeaders } from './request-builder'
4+
import { tryParseJson, errors, buildUrlHeaders } from './utils'
5+
import { logger, workflowLogger } from './logger'
6+
7+
const { EventSourceError } = errors
58

69
/**
710
* Take (CF_ prefixed) Env variables and perform http/s request (SSE) to app-proxy for image-report with CF_ENRICHERS
811
*/
9-
async function mainProcess(argv, env): Promise<void> {
12+
async function main(argv, env): Promise<void> {
1013
const verbose = argv.includes('verbose') || env['VERBOSE']
1114
if (verbose) {
12-
console.debug('Running with verbose log')
15+
logger.debug('running with verbose log')
1316
}
1417
const payload = validate(env)
1518
const { url, headers } = buildUrlHeaders(payload)
1619
if (verbose) {
17-
console.debug(`Payload: ${JSON.stringify(payload, null, 2)}`)
18-
console.debug(`Sending request: ${url}, headers: ${JSON.stringify(headers)}`)
20+
logger.debug(`payload: ${JSON.stringify(payload, null, 2)}`)
21+
logger.debug(`sending request: ${url}, headers: ${JSON.stringify(headers)}`)
1922
}
2023
if (payload['CF_CI_TYPE'] && payload['CF_WORKFLOW_URL']) {
21-
console.info(`Running ${payload['CF_CI_TYPE']} URL: ${payload['CF_WORKFLOW_URL']}`)
24+
logger.info(`CI provider: ${payload['CF_CI_TYPE']}, job URL: ${payload['CF_WORKFLOW_URL']}`)
2225
}
23-
const waitFor = new Promise((resolve, reject) => {
24-
const eventSource = new EventSource(url, { headers })
26+
const eventSource = new EventSource(url, { headers })
27+
const waitFor = new Promise<void>((resolve, reject) => {
28+
2529
eventSource.addEventListener('report', function (event) {
26-
console.info(`report =>`, JSON.stringify(JSON.parse(event.data), null, 2))
30+
logger.info(JSON.stringify(JSON.parse(event.data), null, 2))
2731
})
2832
eventSource.addEventListener('info', function (event) {
29-
console.info(`\t\t${JSON.stringify(event.data)}`)
33+
logger.info(event.data)
3034
})
3135
eventSource.addEventListener('warn', function (event) {
32-
console.warn(`Warning:\t${JSON.stringify(event.data)}`)
36+
logger.warn(event.data)
3337
})
34-
eventSource.addEventListener('error', (err) => {
38+
eventSource.addEventListener('workflow-log', function (event) {
39+
const log = tryParseJson(event.data)
40+
if (typeof log === 'object' && log.content && log.podName) {
41+
workflowLogger.info({ pod: log.podName, message: log.content })
42+
} else {
43+
workflowLogger.info(event.data)
44+
}
45+
})
46+
eventSource.addEventListener('error', (errorEvent) => {
3547
eventSource.close()
36-
reject(err)
48+
49+
const error = tryParseJson(errorEvent.data)
50+
let name
51+
let message
52+
if (typeof error === 'string') {
53+
message = error
54+
} else if (typeof error === 'object') {
55+
if (typeof error.message === 'string') {
56+
message = error.message
57+
}
58+
if (typeof error.name === 'string') {
59+
name = error.name
60+
}
61+
} else {
62+
message = errorEvent.message || 'Unknown error. Something went wrong.'
63+
}
64+
reject(new EventSourceError(message, name))
3765
})
38-
eventSource.addEventListener('end', (ev) => {
66+
eventSource.addEventListener('end', (event) => {
3967
eventSource.close()
40-
resolve(ev)
68+
logger.info(event.data)
69+
resolve()
4170
})
4271
})
4372
await waitFor
4473
}
4574

46-
async function main(argv, env): Promise<void> {
47-
try {
48-
await mainProcess(argv, env)
49-
} catch (error) {
50-
console.error(error)
51-
if (error.type=='error' && error.status===500) {
52-
const tokenStart = (env['CF_API_KEY'] || '').slice(0, 6)
53-
const tokenEnd = (env['CF_API_KEY'] || '').slice(-6)
54-
console.info(`Error 500 are usually caused by providing an invalid CF_API_KEY, please check that the validity of the provided codefresh api token ${tokenStart}..${tokenEnd}`)
55-
}
56-
throw error
57-
}
58-
}
59-
6075
/**
6176
* calling main with process argv and env. Exit code 1 on error
6277
*/
6378
export async function mainErrorHandling() {
6479
try {
6580
await main(process.argv, process.env)
66-
} catch {
67-
// Catchall for general errors
81+
} catch (error) {
82+
logger.error(error.toString())
6883
process.exit(1)
6984
}
7085
}
71-
72-
73-

src/request-builder.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/utils.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
export const tryParseJson = (str: string) => {
2+
try {
3+
return JSON.parse(str)
4+
} catch {
5+
return str
6+
}
7+
}
8+
9+
10+
/**
11+
* Build image-report url and headers
12+
* @param payload
13+
*/
14+
export function buildUrlHeaders(payload: Record<string, string | undefined>) {
15+
const esc = encodeURIComponent
16+
const headers = { 'authorization': payload['CF_API_KEY'] }
17+
const host = payload['CF_HOST'] as string
18+
delete payload['CF_API_KEY']
19+
delete payload['CF_HOST']
20+
const qs = Object.entries(payload).map(kv => `${esc(kv[0])}=${esc(kv[1] || '')}`).join('&')
21+
const url = `${host}/app-proxy/api/image-report?${qs}`
22+
if (payload['CF_LOCAL']) {
23+
return { url: `${host}/api/image-report?${qs}`, headers }
24+
}
25+
return { url, headers }
26+
}
27+
28+
29+
export const errors = {
30+
EventSourceError: class extends Error {
31+
constructor(message?: string, name?: string) {
32+
super(message)
33+
this.name = name || 'EventSourceError'
34+
}
35+
},
36+
ValidationError: class extends Error {
37+
constructor(message?: string, name?: string) {
38+
super(message)
39+
this.name = name || 'ValidationError'
40+
}
41+
}
42+
}

src/validate.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { errors } from './utils'
2+
13
/**
24
* Validate mandatory env vars. address host default
35
*/
@@ -13,8 +15,8 @@ export function validate(payload: Record<string, string|undefined>): Record<stri
1315
if (!filtered['CF_HOST']) {
1416
messages.push(`CF_HOST must be provided as app-proxy http/s address`)
1517
}
16-
if (messages.length>0) {
17-
throw new Error(`Validation Error: ${JSON.stringify(messages)}`)
18+
if (messages.length > 0) {
19+
throw new errors.ValidationError(`Validation Error: ${JSON.stringify(messages)}`)
1820
}
1921

2022
return filtered

0 commit comments

Comments
 (0)