diff --git a/.changeset/quiet-paws-study.md b/.changeset/quiet-paws-study.md index a89c3115bc..ffa18da1e8 100644 --- a/.changeset/quiet-paws-study.md +++ b/.changeset/quiet-paws-study.md @@ -2,4 +2,65 @@ '@backstage/plugin-techdocs-backend': patch --- -Output logs from TechDocs build to a logger in addition to existing frontend event stream +Output logs from a TechDocs build to a logging transport in addition to existing frontend event stream, for capturing these logs to other sources. + +This allows users to capture debugging information around why tech docs fail to build without needing to rely on end users ending information from their web browser. + +The most common use case is to log to the same place as the rest of the backend application logs. + +To use, include + +``` +import { DockerContainerRunner } from '@backstage/backend-common'; +import { + createRouter, + Generators, + Preparers, + Publisher, +} from '@backstage/plugin-techdocs-backend'; +import Docker from 'dockerode'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + // Preparers are responsible for fetching source files for documentation. + const preparers = await Preparers.fromConfig(env.config, { + logger: env.logger, + reader: env.reader, + }); + + // Docker client (conditionally) used by the generators, based on techdocs.generators config. + const dockerClient = new Docker(); + const containerRunner = new DockerContainerRunner({ dockerClient }); + + // Generators are used for generating documentation sites. + const generators = await Generators.fromConfig(env.config, { + logger: env.logger, + containerRunner, + }); + + // Publisher is used for + // 1. Publishing generated files to storage + // 2. Fetching files from storage and passing them to TechDocs frontend. + const publisher = await Publisher.fromConfig(env.config, { + logger: env.logger, + discovery: env.discovery, + }); + + // checks if the publisher is working and logs the result + await publisher.getReadiness(); + + return await createRouter({ + preparers, + generators, + publisher, + logger: env.logger, + buildTransportLogger: env.logger, + config: env.config, + discovery: env.discovery, + cache: env.cache, + }); +} +``` diff --git a/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts b/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts index cec79cda58..fff35bedc0 100644 --- a/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts +++ b/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts @@ -297,7 +297,9 @@ describe('DocsSynchronizer', () => { techdocs: { legacyUseCaseSensitiveTripletPaths: true }, }), logger: getVoidLogger(), - buildLogger: getVoidLogger(), + buildLogTransport: new winston.transports.Stream({ + stream: new PassThrough(), + }), scmIntegrations: ScmIntegrations.fromConfig(new ConfigReader({})), cache, }); @@ -331,7 +333,7 @@ describe('DocsSynchronizer', () => { expect(mockResponseHandler.finish).toBeCalledWith({ updated: false }); }); - it('should log to the build logger', async () => { + it("adds the build log transport to the logger's list of transports", async () => { let logger: winston.Logger; MockedDocsBuilder.prototype.build.mockImplementation(async () => { logger = MockedDocsBuilder.mock.calls[0][0].logger;