Add Cloud Logging Support

This commit is contained in:
caipira113 2023-06-18 07:48:27 +09:00 committed by NoriDev
parent 3b7fe6bafd
commit d04df47f7d
9 changed files with 185 additions and 6 deletions

View file

@ -147,6 +147,12 @@ id: 'aid'
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4
# Cloud Logging
#cloudLogging:
# projectId: example-project-id
# saKeyPath: /path/to/service-account-key.json
# logName: misskey
# Proxy for HTTP/HTTPS
#proxy: http://127.0.0.1:3128

View file

@ -151,6 +151,12 @@ id: 'aid'
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4
# Cloud Logging
#cloudLogging:
# projectId: example-project-id
# saKeyPath: /path/to/service-account-key.json
# logName: misskey
# Proxy for HTTP/HTTPS
#proxy: http://127.0.0.1:3128

View file

@ -147,6 +147,12 @@ id: 'aid'
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4
# Cloud Logging
#cloudLogging:
# projectId: example-project-id
# saKeyPath: /path/to/service-account-key.json
# logName: misskey
# Proxy for HTTP/HTTPS
#proxy: http://127.0.0.1:3128

View file

@ -167,6 +167,12 @@ id: "aid"
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4
# Cloud Logging
#cloudLogging:
# projectId: example-project-id
# saKeyPath: /path/to/service-account-key.json
# logName: misskey
# Proxy for HTTP/HTTPS
#proxy: http://127.0.0.1:3128

View file

@ -65,6 +65,7 @@
"@fastify/multipart": "7.6.0",
"@fastify/static": "6.10.2",
"@fastify/view": "7.4.1",
"@google-cloud/logging": "^10.5.0",
"@google-cloud/translate": "^7.2.1",
"@nestjs/common": "9.4.2",
"@nestjs/core": "9.4.2",
@ -147,6 +148,7 @@
"slacc": "0.0.9",
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
"strip-ansi": "^7.1.0",
"summaly": "github:misskey-dev/summaly",
"systeminformation": "5.17.16",
"tinycolor2": "1.6.0",

View file

@ -90,6 +90,12 @@ export type Source = {
deliverJobMaxAttempts?: number;
inboxJobMaxAttempts?: number;
cloudLogging?: {
projectId: string;
saKeyPath: string;
logName?: string;
}
mediaProxy?: string;
proxyRemoteFiles?: boolean;
videoThumbnailGenerator?: string;

View file

@ -7,14 +7,18 @@ import type { KEYWORD } from 'color-convert/conversions';
@Injectable()
export class LoggerService {
private cloudLogging;
constructor(
@Inject(DI.config)
private config: Config,
) {
if (this.config.cloudLogging) {
this.cloudLogging = this.config.cloudLogging;
}
}
@bindThis
public getLogger(domain: string, color?: KEYWORD | undefined, store?: boolean) {
return new Logger(domain, color, store);
return new Logger(domain, color, store, this.cloudLogging);
}
}

View file

@ -1,7 +1,10 @@
import cluster from 'node:cluster';
import util from 'util';
import chalk from 'chalk';
import { default as convertColor } from 'color-convert';
import { format as dateFormat } from 'date-fns';
import { Logging } from '@google-cloud/logging';
import stripAnsi from 'strip-ansi';
import { bindThis } from '@/decorators.js';
import { envOption } from './env.js';
import type { KEYWORD } from 'color-convert/conversions';
@ -12,18 +15,21 @@ type Context = {
};
type Level = 'error' | 'success' | 'warning' | 'debug' | 'info';
type CloudLogging = any | undefined;
export default class Logger {
private context: Context;
private parentLogger: Logger | null = null;
private store: boolean;
private clConfig?: CloudLogging;
constructor(context: string, color?: KEYWORD, store = true) {
constructor(context: string, color?: KEYWORD, store = true, clConfig?: CloudLogging) {
this.context = {
name: context,
color: color,
};
this.store = store;
this.clConfig = clConfig;
}
@bindThis
@ -44,7 +50,8 @@ export default class Logger {
return;
}
const time = dateFormat(new Date(), 'HH:mm:ss');
const timestamp = new Date();
const time = dateFormat(timestamp, 'HH:mm:ss');
const worker = cluster.isPrimary ? '*' : cluster.worker!.id;
const l =
level === 'error' ? important ? chalk.bgRed.white('ERR ') : chalk.red('ERR ') :
@ -66,7 +73,43 @@ export default class Logger {
if (envOption.withLogTime) log = chalk.gray(time) + ' ' + log;
console.log(important ? chalk.bold(log) : log);
if (level === 'error' && data) console.log(data);
if (level === 'error' && data) {
console.log(data);
this.writeCloudLogging(level, log, timestamp, data);
} else {
this.writeCloudLogging(level, log, timestamp, null);
}
}
private async writeCloudLogging(level: Level, message: string, time: Date, data?: Record<string, any> | null) {
if (!this.clConfig) return;
if (!this.clConfig.projectId || !this.clConfig.saKeyPath) return;
let lv = level;
if (level === 'success') lv = 'info';
const projectId = this.clConfig.projectId;
const logging = new Logging({ projectId: projectId, keyFilename: this.clConfig.saKeyPath });
const logName = this.clConfig.logName ?? 'misskey';
const log = logging.log(logName);
const logMessage = stripAnsi(message);
const metadata = {
severity: lv.toUpperCase(),
resource: {
type: 'global',
timestamp: time,
},
labels: {
name: `${this.context.name}`,
color: `${this.context.color}`,
},
};
const dataString = data ? '\n' + util.inspect(data, { depth: null }) : '';
const entry = log.entry(metadata, logMessage + dataString);
await log.write(entry);
}
@bindThis

View file

@ -110,6 +110,9 @@ importers:
'@fastify/view':
specifier: 7.4.1
version: 7.4.1
'@google-cloud/logging':
specifier: ^10.5.0
version: 10.5.0
'@google-cloud/translate':
specifier: ^7.2.1
version: 7.2.1
@ -356,6 +359,9 @@ importers:
stringz:
specifier: 2.1.0
version: 2.1.0
strip-ansi:
specifier: ^7.1.0
version: 7.1.0
summaly:
specifier: github:misskey-dev/summaly
version: github.com/misskey-dev/summaly/77dd5654bb82280b38c1f50e51a771c33f3df503
@ -4934,6 +4940,38 @@ packages:
- supports-color
dev: false
/@google-cloud/logging@10.5.0:
resolution: {integrity: sha512-XmlNs6B8lDZvFwFB5M55g9ch873AA2rXSuFOczQ3FOAzuyd/qksf18suFJfcrLMu8lYSr3SQhTE45FlXz4p9pg==}
engines: {node: '>=12.0.0'}
dependencies:
'@google-cloud/common': 4.0.3
'@google-cloud/paginator': 4.0.1
'@google-cloud/projectify': 3.0.0
'@google-cloud/promisify': 3.0.1
arrify: 2.0.1
dot-prop: 6.0.1
eventid: 2.0.1
extend: 3.0.2
gcp-metadata: 4.3.1
google-auth-library: 8.8.0
google-gax: 3.6.0
on-finished: 2.4.1
pumpify: 2.0.1
stream-events: 1.0.5
uuid: 9.0.0
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/@google-cloud/paginator@4.0.1:
resolution: {integrity: sha512-6G1ui6bWhNyHjmbYwavdN7mpVPRBtyDg/bfqBTAlwr413On2TnFNfDxc9UhTJctkgoCDgQXEKiRPLPR9USlkbQ==}
engines: {node: '>=12.0.0'}
dependencies:
arrify: 2.0.1
extend: 3.0.2
dev: false
/@google-cloud/projectify@3.0.0:
resolution: {integrity: sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==}
engines: {node: '>=12.0.0'}
@ -9095,6 +9133,11 @@ packages:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
/ansi-regex@6.0.1:
resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
engines: {node: '>=12'}
dev: false
/ansi-styles@2.2.1:
resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==}
engines: {node: '>=0.10.0'}
@ -11549,6 +11592,13 @@ packages:
domelementtype: 2.3.0
domhandler: 5.0.3
/dot-prop@6.0.1:
resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==}
engines: {node: '>=10'}
dependencies:
is-obj: 2.0.0
dev: false
/dotenv-expand@10.0.0:
resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==}
engines: {node: '>=12'}
@ -11616,7 +11666,6 @@ packages:
/ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
dev: true
/ejs@3.1.8:
resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==}
@ -12328,6 +12377,13 @@ packages:
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
dev: false
/eventid@2.0.1:
resolution: {integrity: sha512-sPNTqiMokAvV048P2c9+foqVJzk49o6d4e0D/sq5jog3pw+4kBgyR0gaM1FM7Mx6Kzd9dztesh9oYz1LWWOpzw==}
engines: {node: '>=10'}
dependencies:
uuid: 8.3.2
dev: false
/events@3.3.0:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
@ -13174,6 +13230,20 @@ packages:
wide-align: 1.1.5
dev: false
/gaxios@4.3.3:
resolution: {integrity: sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==}
engines: {node: '>=10'}
dependencies:
abort-controller: 3.0.0
extend: 3.0.2
https-proxy-agent: 5.0.1
is-stream: 2.0.1
node-fetch: 2.6.11
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/gaxios@5.1.0:
resolution: {integrity: sha512-aezGIjb+/VfsJtIcHGcBSerNEDdfdHeMros+RbYbGpmonKWQCOVOes0LVZhn1lDtIgq55qq0HaxymIoae3Fl/A==}
engines: {node: '>=12'}
@ -13187,6 +13257,17 @@ packages:
- supports-color
dev: false
/gcp-metadata@4.3.1:
resolution: {integrity: sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==}
engines: {node: '>=10'}
dependencies:
gaxios: 4.3.3
json-bigint: 1.0.0
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/gcp-metadata@5.2.0:
resolution: {integrity: sha512-aFhhvvNycky2QyhG+dcfEdHBF0FRbYcf39s6WNHUDysKSrbJ5vuFbjydxBcmewtXeV248GP8dWT3ByPNxsyHCw==}
engines: {node: '>=12'}
@ -14521,6 +14602,11 @@ packages:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
/is-obj@2.0.0:
resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
engines: {node: '>=8'}
dev: false
/is-path-cwd@2.2.0:
resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==}
engines: {node: '>=6'}
@ -17196,7 +17282,6 @@ packages:
engines: {node: '>= 0.8'}
dependencies:
ee-first: 1.1.1
dev: true
/on-headers@1.0.2:
resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==}
@ -18514,6 +18599,14 @@ packages:
inherits: 2.0.4
pump: 2.0.1
/pumpify@2.0.1:
resolution: {integrity: sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==}
dependencies:
duplexify: 4.1.2
inherits: 2.0.4
pump: 3.0.0
dev: false
/punycode@2.3.0:
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
engines: {node: '>=6'}
@ -20349,6 +20442,13 @@ packages:
dependencies:
ansi-regex: 5.0.1
/strip-ansi@7.1.0:
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
engines: {node: '>=12'}
dependencies:
ansi-regex: 6.0.1
dev: false
/strip-bom@2.0.0:
resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==}
engines: {node: '>=0.10.0'}