@budibase/backend-core 2.8.22-alpha.4 → 2.8.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +3 -4
- package/dist/src/auth/auth.js.map +1 -1
- package/dist/src/cache/appMetadata.d.ts +1 -7
- package/dist/src/cache/appMetadata.js +8 -5
- package/dist/src/cache/appMetadata.js.map +1 -1
- package/dist/src/cache/user.js.map +1 -1
- package/dist/src/constants/misc.d.ts +0 -2
- package/dist/src/constants/misc.js +0 -2
- package/dist/src/constants/misc.js.map +1 -1
- package/dist/src/db/searchIndexes/searchIndexes.js.map +1 -1
- package/dist/src/db/utils.js +2 -7
- package/dist/src/db/utils.js.map +1 -1
- package/dist/src/environment.d.ts +4 -6
- package/dist/src/environment.js +71 -13
- package/dist/src/environment.js.map +1 -1
- package/dist/src/logging/index.d.ts +1 -1
- package/dist/src/logging/index.js +3 -2
- package/dist/src/logging/index.js.map +1 -1
- package/dist/src/logging/pino/logger.js +24 -40
- package/dist/src/logging/pino/logger.js.map +1 -1
- package/dist/src/users.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -4
- package/src/auth/auth.ts +1 -1
- package/src/cache/appMetadata.ts +8 -10
- package/src/cache/user.ts +1 -1
- package/src/constants/misc.ts +0 -2
- package/src/db/searchIndexes/searchIndexes.ts +1 -1
- package/src/db/utils.ts +3 -9
- package/src/environment.ts +4 -12
- package/src/logging/index.ts +3 -1
- package/src/logging/pino/logger.ts +24 -45
- package/src/users.ts +2 -2
- package/dist/src/logging/system.d.ts +0 -9
- package/dist/src/logging/system.js +0 -101
- package/dist/src/logging/system.js.map +0 -1
- package/src/logging/system.ts +0 -81
- package/src/logging/tests/system.spec.ts +0 -61
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/backend-core",
|
|
3
|
-
"version": "2.8.22
|
|
3
|
+
"version": "2.8.22",
|
|
4
4
|
"description": "Budibase backend core libraries used in server and worker",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@budibase/nano": "10.1.2",
|
|
24
24
|
"@budibase/pouchdb-replication-stream": "1.2.10",
|
|
25
|
-
"@budibase/types": "2.8.22
|
|
25
|
+
"@budibase/types": "2.8.22",
|
|
26
26
|
"@shopify/jest-koa-mocks": "5.0.1",
|
|
27
27
|
"@techpass/passport-openidconnect": "0.3.2",
|
|
28
28
|
"aws-cloudfront-sign": "2.2.0",
|
|
@@ -51,7 +51,6 @@
|
|
|
51
51
|
"pouchdb": "7.3.0",
|
|
52
52
|
"pouchdb-find": "7.2.2",
|
|
53
53
|
"redlock": "4.2.0",
|
|
54
|
-
"rotating-file-stream": "3.1.0",
|
|
55
54
|
"sanitize-s3-objectkey": "0.0.1",
|
|
56
55
|
"semver": "7.3.7",
|
|
57
56
|
"tar-fs": "2.1.1",
|
|
@@ -102,5 +101,5 @@
|
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
103
|
},
|
|
105
|
-
"gitHead": "
|
|
104
|
+
"gitHead": "b0975991ddc123785883f3f871c527290a3ca538"
|
|
106
105
|
}
|
package/src/auth/auth.ts
CHANGED
|
@@ -159,7 +159,7 @@ export async function updateUserOAuth(userId: string, oAuthConfig: any) {
|
|
|
159
159
|
|
|
160
160
|
try {
|
|
161
161
|
const db = getGlobalDB()
|
|
162
|
-
const dbUser = await db.get
|
|
162
|
+
const dbUser = await db.get(userId)
|
|
163
163
|
|
|
164
164
|
//Do not overwrite the refresh token if a valid one is not provided.
|
|
165
165
|
if (typeof details.refreshToken !== "string") {
|
package/src/cache/appMetadata.ts
CHANGED
|
@@ -2,14 +2,9 @@ import { getAppClient } from "../redis/init"
|
|
|
2
2
|
import { doWithDB, DocumentType } from "../db"
|
|
3
3
|
import { Database, App } from "@budibase/types"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
INVALID
|
|
5
|
+
const AppState = {
|
|
6
|
+
INVALID: "invalid",
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
export interface DeletedApp {
|
|
10
|
-
state: AppState
|
|
11
|
-
}
|
|
12
|
-
|
|
13
8
|
const EXPIRY_SECONDS = 3600
|
|
14
9
|
|
|
15
10
|
/**
|
|
@@ -36,7 +31,7 @@ function isInvalid(metadata?: { state: string }) {
|
|
|
36
31
|
* @param {string} appId the id of the app to get metadata from.
|
|
37
32
|
* @returns {object} the app metadata.
|
|
38
33
|
*/
|
|
39
|
-
export async function getAppMetadata(appId: string)
|
|
34
|
+
export async function getAppMetadata(appId: string) {
|
|
40
35
|
const client = await getAppClient()
|
|
41
36
|
// try cache
|
|
42
37
|
let metadata = await client.get(appId)
|
|
@@ -66,8 +61,11 @@ export async function getAppMetadata(appId: string): Promise<App | DeletedApp> {
|
|
|
66
61
|
}
|
|
67
62
|
await client.store(appId, metadata, expiry)
|
|
68
63
|
}
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
// we've stored in the cache an object to tell us that it is currently invalid
|
|
65
|
+
if (isInvalid(metadata)) {
|
|
66
|
+
throw { status: 404, message: "No app metadata found" }
|
|
67
|
+
}
|
|
68
|
+
return metadata as App
|
|
71
69
|
}
|
|
72
70
|
|
|
73
71
|
/**
|
package/src/cache/user.ts
CHANGED
|
@@ -12,7 +12,7 @@ const EXPIRY_SECONDS = 3600
|
|
|
12
12
|
*/
|
|
13
13
|
async function populateFromDB(userId: string, tenantId: string) {
|
|
14
14
|
const db = tenancy.getTenantDB(tenantId)
|
|
15
|
-
const user = await db.get
|
|
15
|
+
const user = await db.get(userId)
|
|
16
16
|
user.budibaseAccess = true
|
|
17
17
|
if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
|
|
18
18
|
const account = await accounts.getAccount(user.email)
|
package/src/constants/misc.ts
CHANGED
|
@@ -20,8 +20,6 @@ export enum Header {
|
|
|
20
20
|
TYPE = "x-budibase-type",
|
|
21
21
|
PREVIEW_ROLE = "x-budibase-role",
|
|
22
22
|
TENANT_ID = "x-budibase-tenant-id",
|
|
23
|
-
VERIFICATION_CODE = "x-budibase-verification-code",
|
|
24
|
-
RETURN_VERIFICATION_CODE = "x-budibase-return-verification-code",
|
|
25
23
|
TOKEN = "x-budibase-token",
|
|
26
24
|
CSRF_TOKEN = "x-csrf-token",
|
|
27
25
|
CORRELATION_ID = "x-budibase-correlation-id",
|
|
@@ -5,7 +5,7 @@ export async function createUserIndex() {
|
|
|
5
5
|
const db = getGlobalDB()
|
|
6
6
|
let designDoc
|
|
7
7
|
try {
|
|
8
|
-
designDoc = await db.get
|
|
8
|
+
designDoc = await db.get("_design/database")
|
|
9
9
|
} catch (err: any) {
|
|
10
10
|
if (err.status === 404) {
|
|
11
11
|
designDoc = { _id: "_design/database" }
|
package/src/db/utils.ts
CHANGED
|
@@ -2,7 +2,7 @@ import env from "../environment"
|
|
|
2
2
|
import { DEFAULT_TENANT_ID, SEPARATOR, DocumentType } from "../constants"
|
|
3
3
|
import { getTenantId, getGlobalDBName } from "../context"
|
|
4
4
|
import { doWithDB, directCouchAllDbs } from "./db"
|
|
5
|
-
import {
|
|
5
|
+
import { getAppMetadata } from "../cache/appMetadata"
|
|
6
6
|
import { isDevApp, isDevAppID, getProdAppID } from "../docIds/conversions"
|
|
7
7
|
import { App, Database } from "@budibase/types"
|
|
8
8
|
import { getStartEndKeyURL } from "../docIds"
|
|
@@ -101,9 +101,7 @@ export async function getAllApps({
|
|
|
101
101
|
const response = await Promise.allSettled(appPromises)
|
|
102
102
|
const apps = response
|
|
103
103
|
.filter(
|
|
104
|
-
(result: any) =>
|
|
105
|
-
result.status === "fulfilled" &&
|
|
106
|
-
result.value?.state !== AppState.INVALID
|
|
104
|
+
(result: any) => result.status === "fulfilled" && result.value != null
|
|
107
105
|
)
|
|
108
106
|
.map(({ value }: any) => value)
|
|
109
107
|
if (!all) {
|
|
@@ -128,11 +126,7 @@ export async function getAppsByIDs(appIds: string[]) {
|
|
|
128
126
|
)
|
|
129
127
|
// have to list the apps which exist, some may have been deleted
|
|
130
128
|
return settled
|
|
131
|
-
.filter(
|
|
132
|
-
promise =>
|
|
133
|
-
promise.status === "fulfilled" &&
|
|
134
|
-
(promise.value as DeletedApp).state !== AppState.INVALID
|
|
135
|
-
)
|
|
129
|
+
.filter(promise => promise.status === "fulfilled")
|
|
136
130
|
.map(promise => (promise as PromiseFulfilledResult<App>).value)
|
|
137
131
|
}
|
|
138
132
|
|
package/src/environment.ts
CHANGED
|
@@ -47,10 +47,7 @@ function httpLogging() {
|
|
|
47
47
|
return process.env.HTTP_LOGGING
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
function
|
|
51
|
-
VERSION: string
|
|
52
|
-
SERVICE_NAME: string
|
|
53
|
-
} {
|
|
50
|
+
function findVersion() {
|
|
54
51
|
function findFileInAncestors(
|
|
55
52
|
fileName: string,
|
|
56
53
|
currentDir: string
|
|
@@ -72,14 +69,10 @@ function getPackageJsonFields(): {
|
|
|
72
69
|
try {
|
|
73
70
|
const packageJsonFile = findFileInAncestors("package.json", process.cwd())
|
|
74
71
|
const content = readFileSync(packageJsonFile!, "utf-8")
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
VERSION: parsedContent.version,
|
|
78
|
-
SERVICE_NAME: parsedContent.name,
|
|
79
|
-
}
|
|
72
|
+
return JSON.parse(content).version
|
|
80
73
|
} catch {
|
|
81
74
|
// throwing an error here is confusing/causes backend-core to be hard to import
|
|
82
|
-
return
|
|
75
|
+
return undefined
|
|
83
76
|
}
|
|
84
77
|
}
|
|
85
78
|
|
|
@@ -161,7 +154,7 @@ const environment = {
|
|
|
161
154
|
ENABLE_SSO_MAINTENANCE_MODE: selfHosted
|
|
162
155
|
? process.env.ENABLE_SSO_MAINTENANCE_MODE
|
|
163
156
|
: false,
|
|
164
|
-
|
|
157
|
+
VERSION: findVersion(),
|
|
165
158
|
DISABLE_PINO_LOGGER: process.env.DISABLE_PINO_LOGGER,
|
|
166
159
|
OFFLINE_MODE: process.env.OFFLINE_MODE,
|
|
167
160
|
_set(key: any, value: any) {
|
|
@@ -169,7 +162,6 @@ const environment = {
|
|
|
169
162
|
// @ts-ignore
|
|
170
163
|
environment[key] = value
|
|
171
164
|
},
|
|
172
|
-
ROLLING_LOG_MAX_SIZE: process.env.ROLLING_LOG_MAX_SIZE || "10M",
|
|
173
165
|
}
|
|
174
166
|
|
|
175
167
|
// clean up any environment variable edge cases
|
package/src/logging/index.ts
CHANGED
|
@@ -1,60 +1,37 @@
|
|
|
1
|
-
import pino, { LoggerOptions } from "pino"
|
|
2
|
-
import pinoPretty from "pino-pretty"
|
|
3
|
-
|
|
4
|
-
import { IdentityType } from "@budibase/types"
|
|
5
1
|
import env from "../../environment"
|
|
2
|
+
import pino, { LoggerOptions } from "pino"
|
|
6
3
|
import * as context from "../../context"
|
|
7
4
|
import * as correlation from "../correlation"
|
|
8
|
-
|
|
9
|
-
import {
|
|
5
|
+
import { IdentityType } from "@budibase/types"
|
|
6
|
+
import { LOG_CONTEXT } from "../index"
|
|
10
7
|
|
|
11
8
|
// LOGGER
|
|
12
9
|
|
|
13
10
|
let pinoInstance: pino.Logger | undefined
|
|
14
11
|
if (!env.DISABLE_PINO_LOGGER) {
|
|
15
|
-
const level = env.LOG_LEVEL
|
|
16
12
|
const pinoOptions: LoggerOptions = {
|
|
17
|
-
level,
|
|
13
|
+
level: env.LOG_LEVEL,
|
|
18
14
|
formatters: {
|
|
19
|
-
level:
|
|
20
|
-
return { level:
|
|
15
|
+
level: label => {
|
|
16
|
+
return { level: label.toUpperCase() }
|
|
21
17
|
},
|
|
22
18
|
bindings: () => {
|
|
23
|
-
|
|
24
|
-
// "service" is being injected in datadog using the pod names,
|
|
25
|
-
// so we should leave it blank to allow the default behaviour if it's not running self-hosted
|
|
26
|
-
return {
|
|
27
|
-
service: env.SERVICE_NAME,
|
|
28
|
-
}
|
|
29
|
-
} else {
|
|
30
|
-
return {}
|
|
31
|
-
}
|
|
19
|
+
return {}
|
|
32
20
|
},
|
|
33
21
|
},
|
|
34
22
|
timestamp: () => `,"timestamp":"${new Date(Date.now()).toISOString()}"`,
|
|
35
23
|
}
|
|
36
24
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
: { stream: process.stdout, level: level as pino.Level }
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
if (env.SELF_HOSTED) {
|
|
49
|
-
destinations.push({
|
|
50
|
-
stream: localFileDestination(),
|
|
51
|
-
level: level as pino.Level,
|
|
52
|
-
})
|
|
25
|
+
if (env.isDev()) {
|
|
26
|
+
pinoOptions.transport = {
|
|
27
|
+
target: "pino-pretty",
|
|
28
|
+
options: {
|
|
29
|
+
singleLine: true,
|
|
30
|
+
},
|
|
31
|
+
}
|
|
53
32
|
}
|
|
54
33
|
|
|
55
|
-
pinoInstance =
|
|
56
|
-
? pino(pinoOptions, pino.multistream(destinations))
|
|
57
|
-
: pino(pinoOptions)
|
|
34
|
+
pinoInstance = pino(pinoOptions)
|
|
58
35
|
|
|
59
36
|
// CONSOLE OVERRIDES
|
|
60
37
|
|
|
@@ -106,13 +83,15 @@ if (!env.DISABLE_PINO_LOGGER) {
|
|
|
106
83
|
|
|
107
84
|
let contextObject = {}
|
|
108
85
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
86
|
+
if (LOG_CONTEXT) {
|
|
87
|
+
contextObject = {
|
|
88
|
+
tenantId: getTenantId(),
|
|
89
|
+
appId: getAppId(),
|
|
90
|
+
automationId: getAutomationId(),
|
|
91
|
+
identityId: identity?._id,
|
|
92
|
+
identityType: identity?.type,
|
|
93
|
+
correlationId: correlation.getId(),
|
|
94
|
+
}
|
|
116
95
|
}
|
|
117
96
|
|
|
118
97
|
const mergingObject: any = {
|
package/src/users.ts
CHANGED
|
@@ -67,9 +67,9 @@ export const bulkUpdateGlobalUsers = async (users: User[]) => {
|
|
|
67
67
|
|
|
68
68
|
export async function getById(id: string, opts?: GetOpts): Promise<User> {
|
|
69
69
|
const db = context.getGlobalDB()
|
|
70
|
-
let user = await db.get
|
|
70
|
+
let user = await db.get(id)
|
|
71
71
|
if (opts?.cleanup) {
|
|
72
|
-
user = removeUserPassword(user)
|
|
72
|
+
user = removeUserPassword(user)
|
|
73
73
|
}
|
|
74
74
|
return user
|
|
75
75
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="pouchdb-core" />
|
|
3
|
-
import * as rfs from "rotating-file-stream";
|
|
4
|
-
export declare function getSingleFileMaxSizeInfo(totalMaxSize: string): {
|
|
5
|
-
size: string;
|
|
6
|
-
totalHistoryFiles: number;
|
|
7
|
-
} | undefined;
|
|
8
|
-
export declare function localFileDestination(): rfs.RotatingFileStream;
|
|
9
|
-
export declare function getLogReadStream(): Buffer;
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.getLogReadStream = exports.localFileDestination = exports.getSingleFileMaxSizeInfo = void 0;
|
|
30
|
-
const fs_1 = __importDefault(require("fs"));
|
|
31
|
-
const path_1 = __importDefault(require("path"));
|
|
32
|
-
const rfs = __importStar(require("rotating-file-stream"));
|
|
33
|
-
const environment_1 = __importDefault(require("../environment"));
|
|
34
|
-
const objectStore_1 = require("../objectStore");
|
|
35
|
-
const logsFileName = `budibase.log`;
|
|
36
|
-
const budibaseLogsHistoryFileName = "budibase-logs-history.txt";
|
|
37
|
-
const logsPath = path_1.default.join((0, objectStore_1.budibaseTempDir)(), "systemlogs");
|
|
38
|
-
function getFullPath(fileName) {
|
|
39
|
-
return path_1.default.join(logsPath, fileName);
|
|
40
|
-
}
|
|
41
|
-
function getSingleFileMaxSizeInfo(totalMaxSize) {
|
|
42
|
-
const regex = /(\d+)([A-Za-z])/;
|
|
43
|
-
const match = totalMaxSize === null || totalMaxSize === void 0 ? void 0 : totalMaxSize.match(regex);
|
|
44
|
-
if (!match) {
|
|
45
|
-
console.warn(`totalMaxSize does not have a valid value`, {
|
|
46
|
-
totalMaxSize,
|
|
47
|
-
});
|
|
48
|
-
return undefined;
|
|
49
|
-
}
|
|
50
|
-
const size = +match[1];
|
|
51
|
-
const unit = match[2];
|
|
52
|
-
if (size === 1) {
|
|
53
|
-
switch (unit) {
|
|
54
|
-
case "B":
|
|
55
|
-
return { size: `${size}B`, totalHistoryFiles: 1 };
|
|
56
|
-
case "K":
|
|
57
|
-
return { size: `${(size * 1000) / 2}B`, totalHistoryFiles: 1 };
|
|
58
|
-
case "M":
|
|
59
|
-
return { size: `${(size * 1000) / 2}K`, totalHistoryFiles: 1 };
|
|
60
|
-
case "G":
|
|
61
|
-
return { size: `${(size * 1000) / 2}M`, totalHistoryFiles: 1 };
|
|
62
|
-
default:
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (size % 2 === 0) {
|
|
67
|
-
return { size: `${size / 2}${unit}`, totalHistoryFiles: 1 };
|
|
68
|
-
}
|
|
69
|
-
return { size: `1${unit}`, totalHistoryFiles: size - 1 };
|
|
70
|
-
}
|
|
71
|
-
exports.getSingleFileMaxSizeInfo = getSingleFileMaxSizeInfo;
|
|
72
|
-
function localFileDestination() {
|
|
73
|
-
const fileInfo = getSingleFileMaxSizeInfo(environment_1.default.ROLLING_LOG_MAX_SIZE);
|
|
74
|
-
const outFile = rfs.createStream(logsFileName, {
|
|
75
|
-
// As we have a rolling size, we want to half the max size
|
|
76
|
-
size: fileInfo === null || fileInfo === void 0 ? void 0 : fileInfo.size,
|
|
77
|
-
path: logsPath,
|
|
78
|
-
maxFiles: (fileInfo === null || fileInfo === void 0 ? void 0 : fileInfo.totalHistoryFiles) || 1,
|
|
79
|
-
immutable: true,
|
|
80
|
-
history: budibaseLogsHistoryFileName,
|
|
81
|
-
initialRotation: false,
|
|
82
|
-
});
|
|
83
|
-
return outFile;
|
|
84
|
-
}
|
|
85
|
-
exports.localFileDestination = localFileDestination;
|
|
86
|
-
function getLogReadStream() {
|
|
87
|
-
const streams = [];
|
|
88
|
-
const historyFile = getFullPath(budibaseLogsHistoryFileName);
|
|
89
|
-
if (fs_1.default.existsSync(historyFile)) {
|
|
90
|
-
const fileContent = fs_1.default.readFileSync(historyFile, "utf-8");
|
|
91
|
-
const historyFiles = fileContent.split("\n");
|
|
92
|
-
for (const historyFile of historyFiles.filter(x => x)) {
|
|
93
|
-
streams.push(fs_1.default.readFileSync(historyFile));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
streams.push(fs_1.default.readFileSync(getFullPath(logsFileName)));
|
|
97
|
-
const combinedContent = Buffer.concat(streams);
|
|
98
|
-
return combinedContent;
|
|
99
|
-
}
|
|
100
|
-
exports.getLogReadStream = getLogReadStream;
|
|
101
|
-
//# sourceMappingURL=system.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/logging/system.ts"],"names":[],"mappings":"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"}
|
package/src/logging/system.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import path from "path"
|
|
3
|
-
import * as rfs from "rotating-file-stream"
|
|
4
|
-
|
|
5
|
-
import env from "../environment"
|
|
6
|
-
import { budibaseTempDir } from "../objectStore"
|
|
7
|
-
|
|
8
|
-
const logsFileName = `budibase.log`
|
|
9
|
-
const budibaseLogsHistoryFileName = "budibase-logs-history.txt"
|
|
10
|
-
|
|
11
|
-
const logsPath = path.join(budibaseTempDir(), "systemlogs")
|
|
12
|
-
|
|
13
|
-
function getFullPath(fileName: string) {
|
|
14
|
-
return path.join(logsPath, fileName)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function getSingleFileMaxSizeInfo(totalMaxSize: string) {
|
|
18
|
-
const regex = /(\d+)([A-Za-z])/
|
|
19
|
-
const match = totalMaxSize?.match(regex)
|
|
20
|
-
if (!match) {
|
|
21
|
-
console.warn(`totalMaxSize does not have a valid value`, {
|
|
22
|
-
totalMaxSize,
|
|
23
|
-
})
|
|
24
|
-
return undefined
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const size = +match[1]
|
|
28
|
-
const unit = match[2]
|
|
29
|
-
if (size === 1) {
|
|
30
|
-
switch (unit) {
|
|
31
|
-
case "B":
|
|
32
|
-
return { size: `${size}B`, totalHistoryFiles: 1 }
|
|
33
|
-
case "K":
|
|
34
|
-
return { size: `${(size * 1000) / 2}B`, totalHistoryFiles: 1 }
|
|
35
|
-
case "M":
|
|
36
|
-
return { size: `${(size * 1000) / 2}K`, totalHistoryFiles: 1 }
|
|
37
|
-
case "G":
|
|
38
|
-
return { size: `${(size * 1000) / 2}M`, totalHistoryFiles: 1 }
|
|
39
|
-
default:
|
|
40
|
-
return undefined
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (size % 2 === 0) {
|
|
45
|
-
return { size: `${size / 2}${unit}`, totalHistoryFiles: 1 }
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return { size: `1${unit}`, totalHistoryFiles: size - 1 }
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function localFileDestination() {
|
|
52
|
-
const fileInfo = getSingleFileMaxSizeInfo(env.ROLLING_LOG_MAX_SIZE)
|
|
53
|
-
const outFile = rfs.createStream(logsFileName, {
|
|
54
|
-
// As we have a rolling size, we want to half the max size
|
|
55
|
-
size: fileInfo?.size,
|
|
56
|
-
path: logsPath,
|
|
57
|
-
maxFiles: fileInfo?.totalHistoryFiles || 1,
|
|
58
|
-
immutable: true,
|
|
59
|
-
history: budibaseLogsHistoryFileName,
|
|
60
|
-
initialRotation: false,
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
return outFile
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function getLogReadStream() {
|
|
67
|
-
const streams = []
|
|
68
|
-
const historyFile = getFullPath(budibaseLogsHistoryFileName)
|
|
69
|
-
if (fs.existsSync(historyFile)) {
|
|
70
|
-
const fileContent = fs.readFileSync(historyFile, "utf-8")
|
|
71
|
-
const historyFiles = fileContent.split("\n")
|
|
72
|
-
for (const historyFile of historyFiles.filter(x => x)) {
|
|
73
|
-
streams.push(fs.readFileSync(historyFile))
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
streams.push(fs.readFileSync(getFullPath(logsFileName)))
|
|
78
|
-
|
|
79
|
-
const combinedContent = Buffer.concat(streams)
|
|
80
|
-
return combinedContent
|
|
81
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { getSingleFileMaxSizeInfo } from "../system"
|
|
2
|
-
|
|
3
|
-
describe("system", () => {
|
|
4
|
-
describe("getSingleFileMaxSizeInfo", () => {
|
|
5
|
-
it.each([
|
|
6
|
-
["100B", "50B"],
|
|
7
|
-
["200K", "100K"],
|
|
8
|
-
["20M", "10M"],
|
|
9
|
-
["4G", "2G"],
|
|
10
|
-
])(
|
|
11
|
-
"Halving even number (%s) returns halved size and 1 history file (%s)",
|
|
12
|
-
(totalValue, expectedMaxSize) => {
|
|
13
|
-
const result = getSingleFileMaxSizeInfo(totalValue)
|
|
14
|
-
expect(result).toEqual({
|
|
15
|
-
size: expectedMaxSize,
|
|
16
|
-
totalHistoryFiles: 1,
|
|
17
|
-
})
|
|
18
|
-
}
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
it.each([
|
|
22
|
-
["5B", "1B", 4],
|
|
23
|
-
["17K", "1K", 16],
|
|
24
|
-
["21M", "1M", 20],
|
|
25
|
-
["3G", "1G", 2],
|
|
26
|
-
])(
|
|
27
|
-
"Halving an odd number (%s) returns as many files as size (-1) (%s)",
|
|
28
|
-
(totalValue, expectedMaxSize, totalHistoryFiles) => {
|
|
29
|
-
const result = getSingleFileMaxSizeInfo(totalValue)
|
|
30
|
-
expect(result).toEqual({
|
|
31
|
-
size: expectedMaxSize,
|
|
32
|
-
totalHistoryFiles,
|
|
33
|
-
})
|
|
34
|
-
}
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
it.each([
|
|
38
|
-
["1B", "1B"],
|
|
39
|
-
["1K", "500B"],
|
|
40
|
-
["1M", "500K"],
|
|
41
|
-
["1G", "500M"],
|
|
42
|
-
])(
|
|
43
|
-
"Halving '%s' returns halved unit (%s)",
|
|
44
|
-
(totalValue, expectedMaxSize) => {
|
|
45
|
-
const result = getSingleFileMaxSizeInfo(totalValue)
|
|
46
|
-
expect(result).toEqual({
|
|
47
|
-
size: expectedMaxSize,
|
|
48
|
-
totalHistoryFiles: 1,
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
it.each([[undefined], [""], ["50"], ["wrongvalue"]])(
|
|
54
|
-
"Halving wrongly formatted value ('%s') returns undefined",
|
|
55
|
-
totalValue => {
|
|
56
|
-
const result = getSingleFileMaxSizeInfo(totalValue!)
|
|
57
|
-
expect(result).toBeUndefined()
|
|
58
|
-
}
|
|
59
|
-
)
|
|
60
|
-
})
|
|
61
|
-
})
|