mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
chore(admin): remove the heap snapshot endpoint (#2814)
This commit is contained in:
1 parent
4ef9c4c65b
commit
34b6ecfbd2
13 files changed
+10
-209
No files matched your search
@@ -1,62 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import {Readable} from 'node:stream';
|
||||
import * as v8 from 'node:v8';
|
||||
import {recordAdminWrite} from '@app/api/admin/AdminAuditRecorder';
|
||||
import {requireAdminACL} from '@app/api/middleware/AdminMiddleware';
|
||||
import {RateLimitMiddleware} from '@app/api/middleware/RateLimitMiddleware';
|
||||
import {OpenAPI} from '@app/api/middleware/ResponseTypeMiddleware';
|
||||
import {RateLimitConfigs} from '@app/api/RateLimitConfig';
|
||||
import type {HonoApp} from '@app/api/types/HonoEnv';
|
||||
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
|
||||
import {HeapSnapshotResponse} from '@fluxer/schema/src/domains/admin/AdminSchemas';
|
||||
|
||||
export function SystemAdminController(app: HonoApp) {
|
||||
app.post(
|
||||
'/admin/system/heap-snapshots',
|
||||
RateLimitMiddleware(RateLimitConfigs.ADMIN_SYSTEM_HEAP_SNAPSHOT),
|
||||
requireAdminACL(AdminACLs.SYSTEM_HEAP_SNAPSHOT),
|
||||
OpenAPI({
|
||||
operationId: 'create_admin_system_heap_snapshot',
|
||||
summary: 'Create a V8 heap snapshot',
|
||||
description:
|
||||
'Writes a V8 heap snapshot of the current process and returns the snapshot file. Used for diagnosing memory leaks. Requires SYSTEM_HEAP_SNAPSHOT permission.',
|
||||
responseSchema: HeapSnapshotResponse,
|
||||
responseContentType: 'application/octet-stream',
|
||||
statusCode: 200,
|
||||
security: 'adminApiKey',
|
||||
tags: 'Admin',
|
||||
}),
|
||||
async (ctx) => {
|
||||
const snapshotPath = path.join('/tmp', `heap-${Date.now()}.heapsnapshot`);
|
||||
try {
|
||||
v8.writeHeapSnapshot(snapshotPath);
|
||||
const stat = fs.statSync(snapshotPath);
|
||||
await recordAdminWrite(ctx, {
|
||||
targetType: 'system',
|
||||
targetId: 0n,
|
||||
action: 'create_heap_snapshot',
|
||||
metadata: {size_bytes: stat.size},
|
||||
});
|
||||
const nodeStream = fs.createReadStream(snapshotPath);
|
||||
const body = Readable.toWeb(nodeStream) as ReadableStream;
|
||||
nodeStream.on('close', () => {
|
||||
fs.unlink(snapshotPath, () => {});
|
||||
});
|
||||
return new Response(body, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'Content-Disposition': `attachment; filename="${path.basename(snapshotPath)}"`,
|
||||
'Content-Length': String(stat.size),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
fs.unlink(snapshotPath, () => {});
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -17,7 +17,6 @@ import {LimitConfigAdminController} from '@app/api/admin/controllers/LimitConfig
|
||||
import {MessageAdminController} from '@app/api/admin/controllers/MessageAdminController';
|
||||
import {ReportAdminController} from '@app/api/admin/controllers/ReportAdminController';
|
||||
import {SearchAdminController} from '@app/api/admin/controllers/SearchAdminController';
|
||||
import {SystemAdminController} from '@app/api/admin/controllers/SystemAdminController';
|
||||
import {SystemDmAdminController} from '@app/api/admin/controllers/SystemDmAdminController';
|
||||
import {UserAdminController} from '@app/api/admin/controllers/UserAdminController';
|
||||
import {VoiceAdminController} from '@app/api/admin/controllers/VoiceAdminController';
|
||||
@@ -43,6 +42,5 @@ export function registerAdminControllers(app: HonoApp) {
|
||||
SearchAdminController(app);
|
||||
DiscoveryAdminController(app);
|
||||
SystemDmAdminController(app);
|
||||
SystemAdminController(app);
|
||||
JobsAdminController(app);
|
||||
}
|
||||
@@ -19,7 +19,6 @@ import {LimitConfigAdminAuditCases} from '@app/api/admin/tests/audit_coverage/Li
|
||||
import {MessageAdminAuditCases} from '@app/api/admin/tests/audit_coverage/MessageAdminAuditCases';
|
||||
import {ReportAdminAuditCases} from '@app/api/admin/tests/audit_coverage/ReportAdminAuditCases';
|
||||
import {SearchAdminAuditCases} from '@app/api/admin/tests/audit_coverage/SearchAdminAuditCases';
|
||||
import {SystemAdminAuditCases} from '@app/api/admin/tests/audit_coverage/SystemAdminAuditCases';
|
||||
import {SystemDmAdminAuditCases} from '@app/api/admin/tests/audit_coverage/SystemDmAdminAuditCases';
|
||||
import {UserAdminAuditCases} from '@app/api/admin/tests/audit_coverage/UserAdminAuditCases';
|
||||
import {UserWriteAdminAuditCases} from '@app/api/admin/tests/audit_coverage/UserWriteAdminAuditCases';
|
||||
@@ -46,7 +45,6 @@ const ALL_CASES = [
|
||||
...MessageAdminAuditCases,
|
||||
...ReportAdminAuditCases,
|
||||
...SearchAdminAuditCases,
|
||||
...SystemAdminAuditCases,
|
||||
...SystemDmAdminAuditCases,
|
||||
...UserAdminAuditCases,
|
||||
...UserWriteAdminAuditCases,
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {AdminAuditCoverageCase} from '@app/api/admin/tests/audit_coverage/AdminAuditCoverage';
|
||||
import {expect} from 'vitest';
|
||||
|
||||
export const SystemAdminAuditCases: ReadonlyArray<AdminAuditCoverageCase> = [
|
||||
{
|
||||
method: 'POST',
|
||||
route: '/admin/system/heap-snapshots',
|
||||
async prepare() {
|
||||
return {
|
||||
request: {path: '/admin/system/heap-snapshots'},
|
||||
expected: {
|
||||
action: 'create_heap_snapshot',
|
||||
targetType: 'system',
|
||||
targetId: '0',
|
||||
metadata: {size_bytes: expect.any(String)},
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -1,6 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {describeAdminAuditCoverage} from '@app/api/admin/tests/audit_coverage/AdminAuditCoverage';
|
||||
import {SystemAdminAuditCases} from '@app/api/admin/tests/audit_coverage/SystemAdminAuditCases';
|
||||
|
||||
describeAdminAuditCoverage('SystemAdminController', SystemAdminAuditCases);
|
||||
@@ -48,8 +48,4 @@ export const AdminRateLimitConfigs = {
|
||||
bucket: 'admin:general',
|
||||
config: {limit: 200, windowMs: ms('1 minute')},
|
||||
} as RouteRateLimitConfig,
|
||||
ADMIN_SYSTEM_HEAP_SNAPSHOT: {
|
||||
bucket: 'admin:system:heap_snapshot',
|
||||
config: {limit: 2, windowMs: ms('5 minutes')},
|
||||
} as RouteRateLimitConfig,
|
||||
} as const;
|
||||
Reference in new issue
Block a user