Add logs endpoint
This commit is contained in:
parent
61abb7541a
commit
bb28d09eab
|
@ -1,6 +1,7 @@
|
|||
export * as correlation from "./correlation/correlation"
|
||||
export { logger } from "./pino/logger"
|
||||
export * from "./alerts"
|
||||
export * as system from "./system"
|
||||
|
||||
// turn off or on context logging i.e. tenantId, appId etc
|
||||
export let LOG_CONTEXT = true
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
import fs from "fs"
|
||||
import path from "path"
|
||||
import * as rfs from "rotating-file-stream"
|
||||
|
||||
import env from "../environment"
|
||||
import { budibaseTempDir } from "../objectStore"
|
||||
|
||||
export function localFileDestination() {
|
||||
const fileName = path.join(budibaseTempDir(), `budibase.logs`)
|
||||
const outFile = rfs.createStream(fileName, {
|
||||
size: env.ROLLING_LOG_MAX_SIZE,
|
||||
teeToStdout: true,
|
||||
})
|
||||
|
||||
outFile.on("rotation", () => {
|
||||
fs.copyFileSync(fileName, `${fileName}.bak`)
|
||||
})
|
||||
|
||||
return outFile
|
||||
}
|
|
@ -8,7 +8,7 @@ import * as context from "../../context"
|
|||
import * as correlation from "../correlation"
|
||||
import { LOG_CONTEXT } from "../index"
|
||||
|
||||
import { localFileDestination } from "../localLogging"
|
||||
import { localFileDestination } from "../system"
|
||||
|
||||
// LOGGER
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import fs from "fs"
|
||||
import path from "path"
|
||||
import * as rfs from "rotating-file-stream"
|
||||
|
||||
import env from "../environment"
|
||||
import { budibaseTempDir } from "../objectStore"
|
||||
|
||||
const logsFileName = path.join(budibaseTempDir(), `budibase.logs`)
|
||||
const rollingFileName = `${logsFileName}.bak`
|
||||
|
||||
export function localFileDestination() {
|
||||
const outFile = rfs.createStream(logsFileName, {
|
||||
size: env.ROLLING_LOG_MAX_SIZE,
|
||||
teeToStdout: true,
|
||||
})
|
||||
|
||||
outFile.on("rotation", () => {
|
||||
fs.copyFileSync(logsFileName, rollingFileName)
|
||||
})
|
||||
|
||||
return outFile
|
||||
}
|
||||
|
||||
export function getLogReadStream() {
|
||||
const logsContent = fs.readFileSync(logsFileName)
|
||||
if (!fs.existsSync(rollingFileName)) {
|
||||
return logsContent
|
||||
}
|
||||
|
||||
const rollingContent = fs.readFileSync(rollingFileName)
|
||||
const combinedContent = Buffer.concat([logsContent, rollingContent])
|
||||
return combinedContent
|
||||
}
|
|
@ -30,6 +30,7 @@ import { buildBackupsEndpoints } from "./backups"
|
|||
import { buildEnvironmentVariableEndpoints } from "./environmentVariables"
|
||||
import { buildEventEndpoints } from "./events"
|
||||
import { buildAuditLogsEndpoints } from "./auditLogs"
|
||||
import { buildLogsEndpoints } from "./logs"
|
||||
|
||||
/**
|
||||
* Random identifier to uniquely identify a session in a tab. This is
|
||||
|
@ -277,5 +278,6 @@ export const createAPIClient = config => {
|
|||
...buildEnvironmentVariableEndpoints(API),
|
||||
...buildEventEndpoints(API),
|
||||
...buildAuditLogsEndpoints(API),
|
||||
...buildLogsEndpoints(API),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
export const buildLogsEndpoints = API => ({
|
||||
/**
|
||||
* Gets a list of datasources.
|
||||
*/
|
||||
getServerLogs: async () => {
|
||||
return await API.get({
|
||||
url: "/api/global/system/logs",
|
||||
json: false,
|
||||
parseResponse: async response => {
|
||||
return response
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
|
@ -11,3 +11,17 @@ export function downloadText(filename, text) {
|
|||
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
|
||||
export async function downloadStream(filename, streamResponse) {
|
||||
const blob = await streamResponse.blob()
|
||||
const resBlob = new Blob([blob])
|
||||
|
||||
const blobUrl = URL.createObjectURL(resBlob)
|
||||
|
||||
const link = document.createElement("a")
|
||||
link.href = blobUrl
|
||||
link.download = filename
|
||||
link.click()
|
||||
|
||||
URL.revokeObjectURL(blobUrl)
|
||||
}
|
||||
|
|
|
@ -5,4 +5,4 @@ export * as RoleUtils from "./roles"
|
|||
export * as Utils from "./utils"
|
||||
export { memo, derivedMemo } from "./memo"
|
||||
export { createWebsocket } from "./websocket"
|
||||
export { downloadText } from "./download"
|
||||
export * from "./download"
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { UserCtx } from "@budibase/types"
|
||||
import { logging } from "@budibase/backend-core"
|
||||
|
||||
export async function getLogs(ctx: UserCtx) {
|
||||
const logReadStream = logging.system.getLogReadStream()
|
||||
|
||||
ctx.body = logReadStream
|
||||
}
|
|
@ -16,6 +16,7 @@ import licenseRoutes from "./global/license"
|
|||
import migrationRoutes from "./system/migrations"
|
||||
import accountRoutes from "./system/accounts"
|
||||
import restoreRoutes from "./system/restore"
|
||||
import systemLogRoutes from "./system/logs"
|
||||
|
||||
export const routes: Router[] = [
|
||||
configRoutes,
|
||||
|
@ -37,4 +38,5 @@ export const routes: Router[] = [
|
|||
restoreRoutes,
|
||||
eventRoutes,
|
||||
pro.scim,
|
||||
systemLogRoutes,
|
||||
]
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import Router from "@koa/router"
|
||||
import { middleware } from "@budibase/backend-core"
|
||||
import * as controller from "../../controllers/system/logs"
|
||||
|
||||
const router: Router = new Router()
|
||||
|
||||
router.get("/api/global/system/logs", middleware.adminOnly, controller.getLogs)
|
||||
|
||||
export default router
|
Loading…
Reference in New Issue