Add logs endpoint
This commit is contained in:
parent
61abb7541a
commit
bb28d09eab
|
@ -1,6 +1,7 @@
|
||||||
export * as correlation from "./correlation/correlation"
|
export * as correlation from "./correlation/correlation"
|
||||||
export { logger } from "./pino/logger"
|
export { logger } from "./pino/logger"
|
||||||
export * from "./alerts"
|
export * from "./alerts"
|
||||||
|
export * as system from "./system"
|
||||||
|
|
||||||
// turn off or on context logging i.e. tenantId, appId etc
|
// turn off or on context logging i.e. tenantId, appId etc
|
||||||
export let LOG_CONTEXT = true
|
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 * as correlation from "../correlation"
|
||||||
import { LOG_CONTEXT } from "../index"
|
import { LOG_CONTEXT } from "../index"
|
||||||
|
|
||||||
import { localFileDestination } from "../localLogging"
|
import { localFileDestination } from "../system"
|
||||||
|
|
||||||
// LOGGER
|
// 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 { buildEnvironmentVariableEndpoints } from "./environmentVariables"
|
||||||
import { buildEventEndpoints } from "./events"
|
import { buildEventEndpoints } from "./events"
|
||||||
import { buildAuditLogsEndpoints } from "./auditLogs"
|
import { buildAuditLogsEndpoints } from "./auditLogs"
|
||||||
|
import { buildLogsEndpoints } from "./logs"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Random identifier to uniquely identify a session in a tab. This is
|
* Random identifier to uniquely identify a session in a tab. This is
|
||||||
|
@ -277,5 +278,6 @@ export const createAPIClient = config => {
|
||||||
...buildEnvironmentVariableEndpoints(API),
|
...buildEnvironmentVariableEndpoints(API),
|
||||||
...buildEventEndpoints(API),
|
...buildEventEndpoints(API),
|
||||||
...buildAuditLogsEndpoints(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)
|
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 * as Utils from "./utils"
|
||||||
export { memo, derivedMemo } from "./memo"
|
export { memo, derivedMemo } from "./memo"
|
||||||
export { createWebsocket } from "./websocket"
|
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 migrationRoutes from "./system/migrations"
|
||||||
import accountRoutes from "./system/accounts"
|
import accountRoutes from "./system/accounts"
|
||||||
import restoreRoutes from "./system/restore"
|
import restoreRoutes from "./system/restore"
|
||||||
|
import systemLogRoutes from "./system/logs"
|
||||||
|
|
||||||
export const routes: Router[] = [
|
export const routes: Router[] = [
|
||||||
configRoutes,
|
configRoutes,
|
||||||
|
@ -37,4 +38,5 @@ export const routes: Router[] = [
|
||||||
restoreRoutes,
|
restoreRoutes,
|
||||||
eventRoutes,
|
eventRoutes,
|
||||||
pro.scim,
|
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