Move the logging one level up to send all logs and exceptions to the user

With this change, only failed builds are logged to the backend logger

Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com>
This commit is contained in:
Dominik Henneke
2021-07-09 14:24:16 +02:00
parent 380a519b2d
commit 800445cca0
7 changed files with 83 additions and 44 deletions
@@ -120,6 +120,7 @@ export class DocsBuilder {
try {
const preparerResponse = await this.preparer.prepare(this.entity, {
etag: storedEtag,
logger: this.logger,
});
preparedDir = preparerResponse.preparedDir;
@@ -171,6 +172,7 @@ export class DocsBuilder {
outputDir,
parsedLocationAnnotation,
etag: newEtag,
logger: this.logger,
logStream: this.logStream,
});
@@ -230,6 +230,47 @@ describe('DocsSynchronizer', () => {
expect(DocsBuilder.prototype.build).toBeCalledTimes(0);
});
it('should forward build errors', async () => {
(shouldCheckForUpdate as jest.Mock).mockReturnValue(true);
MockedConfigReader.prototype.getString.mockReturnValue('local');
const entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
uid: '0',
name: 'test',
namespace: 'default',
annotations: {
'sda.se/release-notes-location':
'github-releases:https://github.com/backstage/backstage',
},
},
};
catalogClient.getEntityByName.mockResolvedValue(entity);
const error = new Error('Some random error');
MockedDocsBuilder.prototype.build.mockRejectedValue(error);
await docsSynchronizer.doSync(() => mockResponseHandler, {
kind: 'Component',
namespace: 'default',
name: 'test',
token: undefined,
});
expect(mockResponseHandler.log).toBeCalledTimes(1);
expect(mockResponseHandler.log).toBeCalledWith(
expect.stringMatching(
/error.*: Failed to build the docs page: Some random error/,
),
);
expect(mockResponseHandler.finish).toBeCalledTimes(0);
expect(mockResponseHandler.error).toBeCalledTimes(1);
expect(mockResponseHandler.error).toBeCalledWith(error);
});
it('rejects when entity is not found', async () => {
catalogClient.getEntityByName.mockResolvedValue(undefined);
@@ -23,7 +23,7 @@ import {
PublisherBase,
} from '@backstage/techdocs-common';
import { PassThrough } from 'stream';
import { Logger } from 'winston';
import * as winston from 'winston';
import { DocsBuilder, shouldCheckForUpdate } from '../DocsBuilder';
export type DocsSynchronizerSyncOpts = {
@@ -36,7 +36,7 @@ export class DocsSynchronizer {
private readonly preparers: PreparerBuilder;
private readonly generators: GeneratorBuilder;
private readonly publisher: PublisherBase;
private readonly logger: Logger;
private readonly logger: winston.Logger;
private readonly config: Config;
private readonly catalogClient: CatalogApi;
@@ -51,7 +51,7 @@ export class DocsSynchronizer {
preparers: PreparerBuilder;
generators: GeneratorBuilder;
publisher: PublisherBase;
logger: Logger;
logger: winston.Logger;
config: Config;
catalogClient: CatalogApi;
}) {
@@ -88,12 +88,26 @@ export class DocsSynchronizer {
// open the event-stream
const { log, error, finish } = initResponseHandler();
// create a new logger to log data to the caller
const taskLogger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: winston.format.combine(
winston.format.colorize(),
winston.format.timestamp(),
winston.format.simple(),
),
defaultMeta: {},
});
// create an in-memory stream to forward logs to the event-stream
const logStream = new PassThrough();
logStream.on('data', async data => {
log(data.toString().trim());
});
taskLogger.add(new winston.transports.Stream({ stream: logStream }));
// check if the last update check was too recent
if (!shouldCheckForUpdate(entity.metadata.uid)) {
finish({ updated: false });
@@ -112,7 +126,7 @@ export class DocsSynchronizer {
preparers: this.preparers,
generators: this.generators,
publisher: this.publisher,
logger: this.logger,
logger: taskLogger,
entity,
config: this.config,
logStream,
@@ -120,10 +134,18 @@ export class DocsSynchronizer {
let foundDocs = false;
const updated = await docsBuilder.build();
try {
const updated = await docsBuilder.build();
if (!updated) {
finish({ updated: false });
if (!updated) {
finish({ updated: false });
return;
}
} catch (e) {
const msg = `Failed to build the docs page: ${e.message}`;
taskLogger.error(msg);
this.logger.error(msg, e);
error(e);
return;
}