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 registerProcessProvider from "./process";
export default () => {
registerDBPingProvider();
registerDBServiceProvider();
registerStorageServiceProvider();
registerPlatformProvider();
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 { randomUUID } from "crypto";
import _ from "lodash";
import { TDiagnosticResult, TServiceDiagnosticDepth } from "../../../../framework/api/diagnostics";
export type S3Configuration = {
id: string;
@@ -43,6 +44,20 @@ export default class S3ConnectorService implements StorageConnectorAPI {
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> {
return new Promise((resolve, reject) => {
let totalSize = 0;
@@ -6,6 +6,7 @@ import { StorageConnectorAPI, WriteMetadata } from "../../provider";
import fs from "fs";
import { logger } from "../../../../framework/logger";
import { randomUUID } from "crypto";
import { TDiagnosticResult, TServiceDiagnosticDepth } from "../../../../framework/api/diagnostics";
export type LocalConfiguration = {
id: string;
@@ -29,6 +30,19 @@ export default class LocalConnectorService implements StorageConnectorAPI {
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> {
const path = this.getFullPath(relativePath);
logger.trace(`Writing file ${path}`);
@@ -19,6 +19,10 @@ export class DefaultStorageStrategy implements StorageConnectorAPI {
return this.connector.getId();
}
getDiagnostics(depth) {
return this.connector.getDiagnostics(depth);
}
write = (
path: string,
stream: Stream,
@@ -8,6 +8,7 @@ import {
} from "../storage/provider";
import { logger } from "../../../platform/framework";
import { FileNotFountException, WriteFileException } from "./exceptions";
import type { TDiagnosticResult, TServiceDiagnosticDepth } from "../../framework/api/diagnostics";
/**
* OneOfStorageStrategy is responsible for managing multiple storage backends.
@@ -34,6 +35,17 @@ export class OneOfStorageStrategy implements StorageConnectorAPI {
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.
* The write operation is considered successful if one of the storage succeed.
@@ -1,6 +1,7 @@
import { Stream, Readable } from "stream";
import { TdriveServiceProvider } from "../../framework";
import { ExecutionContext } from "../../framework/api/crud-service";
import { IServiceDiagnosticProvider } from "../../framework/api/diagnostics";
export type WriteMetadata = {
size: number;
@@ -22,7 +23,7 @@ export type DeleteOptions = {
totalChunks?: number;
};
export interface StorageConnectorAPI {
export interface StorageConnectorAPI extends IServiceDiagnosticProvider {
/**
* 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;
}
getDiagnostics(depth) {
return this.getConnector().getDiagnostics(depth);
}
getHomeDir(): string {
return this.homeDir;
}