back: adding storage service diagnostics (#762)

This commit is contained in:
Eric Doughty-Papassideris
2024-12-08 22:53:43 +01:00
parent 150dadeab5
commit 7c0f359759
8 changed files with 64 additions and 3 deletions
@@ -1,9 +1,11 @@
import registerDBPingProvider from "./database-service"; import registerDBServiceProvider from "./database-service";
import registerStorageServiceProvider from "./storage-service";
import registerPlatformProvider from "./platform-started"; import registerPlatformProvider from "./platform-started";
import registerProcessProvider from "./process"; import registerProcessProvider from "./process";
export default () => { export default () => {
registerDBPingProvider(); registerDBServiceProvider();
registerStorageServiceProvider();
registerPlatformProvider(); registerPlatformProvider();
registerProcessProvider(); registerProcessProvider();
}; };
@@ -0,0 +1,9 @@
import diagnostics from "../../../framework/api/diagnostics";
import globalResolver from "../../../../../services/global-resolver";
export default () =>
diagnostics.registerServiceProviders("storage", () => globalResolver.platformServices.storage, {
stats_basic: false,
stats_track: false,
stats_deep: false,
});
@@ -4,6 +4,7 @@ import { Readable } from "stream";
import { StorageConnectorAPI, WriteMetadata } from "../../provider"; import { StorageConnectorAPI, WriteMetadata } from "../../provider";
import { randomUUID } from "crypto"; import { randomUUID } from "crypto";
import _ from "lodash"; import _ from "lodash";
import { TDiagnosticResult, TServiceDiagnosticDepth } from "../../../../framework/api/diagnostics";
export type S3Configuration = { export type S3Configuration = {
id: string; id: string;
@@ -43,6 +44,20 @@ export default class S3ConnectorService implements StorageConnectorAPI {
return this.id; return this.id;
} }
async getDiagnostics(depth: TServiceDiagnosticDepth): Promise<TDiagnosticResult> {
switch (depth) {
case TServiceDiagnosticDepth.alive:
return { ok: await this.client.bucketExists(this.minioConfiguration.bucket) };
case TServiceDiagnosticDepth.stats_basic:
case TServiceDiagnosticDepth.stats_track:
case TServiceDiagnosticDepth.stats_deep:
return { ok: true, warn: "s3_statistics_not_implemented" };
default:
throw new Error(`Unexpected TServiceDiagnosticDepth: ${JSON.stringify(depth)}`);
}
}
write(path: string, stream: Readable): Promise<WriteMetadata> { write(path: string, stream: Readable): Promise<WriteMetadata> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let totalSize = 0; let totalSize = 0;
@@ -6,6 +6,7 @@ import { StorageConnectorAPI, WriteMetadata } from "../../provider";
import fs from "fs"; import fs from "fs";
import { logger } from "../../../../framework/logger"; import { logger } from "../../../../framework/logger";
import { randomUUID } from "crypto"; import { randomUUID } from "crypto";
import { TDiagnosticResult, TServiceDiagnosticDepth } from "../../../../framework/api/diagnostics";
export type LocalConfiguration = { export type LocalConfiguration = {
id: string; id: string;
@@ -29,6 +30,19 @@ export default class LocalConnectorService implements StorageConnectorAPI {
return this.id; return this.id;
} }
async getDiagnostics(depth: TServiceDiagnosticDepth): Promise<TDiagnosticResult> {
switch (depth) {
case TServiceDiagnosticDepth.alive:
case TServiceDiagnosticDepth.stats_basic:
case TServiceDiagnosticDepth.stats_track:
case TServiceDiagnosticDepth.stats_deep:
return { ok: true, warn: "local_s3_alway_ok" };
default:
throw new Error(`Unexpected TServiceDiagnosticDepth: ${JSON.stringify(depth)}`);
}
}
write(relativePath: string, stream: Readable): Promise<WriteMetadata> { write(relativePath: string, stream: Readable): Promise<WriteMetadata> {
const path = this.getFullPath(relativePath); const path = this.getFullPath(relativePath);
logger.trace(`Writing file ${path}`); logger.trace(`Writing file ${path}`);
@@ -19,6 +19,10 @@ export class DefaultStorageStrategy implements StorageConnectorAPI {
return this.connector.getId(); return this.connector.getId();
} }
getDiagnostics(depth) {
return this.connector.getDiagnostics(depth);
}
write = ( write = (
path: string, path: string,
stream: Stream, stream: Stream,
@@ -8,6 +8,7 @@ import {
} from "../storage/provider"; } from "../storage/provider";
import { logger } from "../../../platform/framework"; import { logger } from "../../../platform/framework";
import { FileNotFountException, WriteFileException } from "./exceptions"; import { FileNotFountException, WriteFileException } from "./exceptions";
import type { TDiagnosticResult, TServiceDiagnosticDepth } from "../../framework/api/diagnostics";
/** /**
* OneOfStorageStrategy is responsible for managing multiple storage backends. * OneOfStorageStrategy is responsible for managing multiple storage backends.
@@ -34,6 +35,17 @@ export class OneOfStorageStrategy implements StorageConnectorAPI {
return this.id; return this.id;
} }
async getDiagnostics(depth: TServiceDiagnosticDepth): Promise<TDiagnosticResult> {
const states = await Promise.all(
this.storages.map(async s => ({ id: s.getId(), ...(await s.getDiagnostics(depth)) })),
);
return {
...(states.every(s => s.ok) ? {} : { warn: "not_all_storages_ok" }),
ok: states.some(s => s.ok),
states: states,
};
}
/** /**
* Writes a file to all configured storages. * Writes a file to all configured storages.
* The write operation is considered successful if one of the storage succeed. * The write operation is considered successful if one of the storage succeed.
@@ -1,6 +1,7 @@
import { Stream, Readable } from "stream"; import { Stream, Readable } from "stream";
import { TdriveServiceProvider } from "../../framework"; import { TdriveServiceProvider } from "../../framework";
import { ExecutionContext } from "../../framework/api/crud-service"; import { ExecutionContext } from "../../framework/api/crud-service";
import { IServiceDiagnosticProvider } from "../../framework/api/diagnostics";
export type WriteMetadata = { export type WriteMetadata = {
size: number; size: number;
@@ -22,7 +23,7 @@ export type DeleteOptions = {
totalChunks?: number; totalChunks?: number;
}; };
export interface StorageConnectorAPI { export interface StorageConnectorAPI extends IServiceDiagnosticProvider {
/** /**
* Returns identifier of a storage that should've been set in configuration. * Returns identifier of a storage that should've been set in configuration.
* *
@@ -64,6 +64,10 @@ export default class StorageService extends TdriveService<StorageAPI> implements
return this.connector; return this.connector;
} }
getDiagnostics(depth) {
return this.getConnector().getDiagnostics(depth);
}
getHomeDir(): string { getHomeDir(): string {
return this.homeDir; return this.homeDir;
} }