chore(admin): remove the heap snapshot endpoint (#2814)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-16 18:56:01 +02:00
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;