## 概要 [Task3880: Azure Functions実装(音声ファイル削除)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3880) - 自動音声ファイル削除を実装 - 上記のテストを実装 - テストにMySQLを使用する仕組みを導入 ## レビューポイント - テストケースは十分か - テスト内容は妥当か - developにデプロイする前の動作確認・ユニットテストとして十分か ## クエリの変更 - 新規処理のため、既存からの変更はなし ## 動作確認状況 - DBが空の状態でローカル環境で実行し、0件削除のログが出ることを確認 - 削除対象が正しいか等はdevelopでチェック予定 - 行った修正がデグレを発生させていないことを確認できるか - 既存処理の変更はなし
130 lines
3.1 KiB
TypeScript
130 lines
3.1 KiB
TypeScript
import { Logger, QueryRunner } from "typeorm";
|
|
import * as fs from "fs";
|
|
import * as path from "path";
|
|
|
|
interface IOutput {
|
|
initialize(): void;
|
|
write(message: string): void;
|
|
}
|
|
|
|
class ConsoleOutput implements IOutput {
|
|
initialize(): void {
|
|
// do nothing
|
|
}
|
|
|
|
write(message: string): void {
|
|
console.log(message);
|
|
}
|
|
}
|
|
|
|
class FileOutput implements IOutput {
|
|
private logPath = path.join("/app/dictation_function/.test", "logs");
|
|
private fileName = new Date().getTime();
|
|
|
|
initialize(): void {
|
|
if (!fs.existsSync(this.logPath)) {
|
|
fs.mkdirSync(this.logPath, { recursive: true });
|
|
}
|
|
}
|
|
|
|
write(message: string): void {
|
|
const logFile = path.join(this.logPath, `${this.fileName}.log`);
|
|
fs.appendFileSync(logFile, `${message}\n`);
|
|
}
|
|
}
|
|
|
|
class NoneOutput implements IOutput {
|
|
initialize(): void {
|
|
// do nothing
|
|
}
|
|
|
|
write(message: string): void {
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
export class TestLogger implements Logger {
|
|
out: IOutput;
|
|
|
|
constructor(output: "none" | "file" | "console") {
|
|
switch (output) {
|
|
case "none":
|
|
this.out = new NoneOutput();
|
|
break;
|
|
case "file":
|
|
this.out = new FileOutput();
|
|
break;
|
|
case "console":
|
|
this.out = new ConsoleOutput();
|
|
break;
|
|
default:
|
|
this.out = new NoneOutput();
|
|
break;
|
|
}
|
|
this.out.initialize();
|
|
}
|
|
|
|
private write(message: string): void {
|
|
this.out.write(message);
|
|
}
|
|
|
|
logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner) {
|
|
const raw = `Query: ${query} -- Parameters: ${JSON.stringify(parameters)}`;
|
|
// ex: 2024-03-08T06:38:43.125Z を TIME という文字列に置換
|
|
const dateRemoved = raw.replace(
|
|
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/g,
|
|
"TIME"
|
|
);
|
|
// ex: /* コメント内容 */ を /* コメント */ という文字列に置換
|
|
const commentRemoved = dateRemoved.replace(
|
|
/\/\*.*\*\//g,
|
|
"/* RequestID */"
|
|
);
|
|
|
|
// UUIDを固定文字列に置換する ex: 88a9c78e-115a-439c-9e23-731d649f0c27 を XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX という文字列に置換
|
|
const uuidRemoved = commentRemoved.replace(
|
|
/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g,
|
|
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
|
);
|
|
this.write(uuidRemoved);
|
|
}
|
|
|
|
logQueryError(
|
|
error: string,
|
|
query: string,
|
|
parameters?: any[],
|
|
queryRunner?: QueryRunner
|
|
) {
|
|
this.write(
|
|
`ERROR: ${error} -- Query: ${query} -- Parameters: ${JSON.stringify(
|
|
parameters
|
|
)}`
|
|
);
|
|
}
|
|
|
|
logQuerySlow(
|
|
time: number,
|
|
query: string,
|
|
parameters?: any[],
|
|
queryRunner?: QueryRunner
|
|
) {
|
|
this.write(
|
|
`SLOW QUERY: ${time}ms -- Query: ${query} -- Parameters: ${JSON.stringify(
|
|
parameters
|
|
)}`
|
|
);
|
|
}
|
|
|
|
logSchemaBuild(message: string, queryRunner?: QueryRunner) {
|
|
this.write(`Schema Build: ${message}`);
|
|
}
|
|
|
|
logMigration(message: string, queryRunner?: QueryRunner) {
|
|
this.write(`Migration: ${message}`);
|
|
}
|
|
|
|
log(level: "log" | "info" | "warn", message: any, queryRunner?: QueryRunner) {
|
|
this.write(`${level.toUpperCase()}: ${message}`);
|
|
}
|
|
}
|