enhance: ジョブのログを表示できるように
This commit is contained in:
parent
2a836047e3
commit
1082145c74
|
@ -810,6 +810,13 @@ export class QueueService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@bindThis
|
||||||
|
public async queueGetJobLogs(queueType: typeof QUEUE_TYPES[number], jobId: string) {
|
||||||
|
const queue = this.getQueue(queueType);
|
||||||
|
const result = await queue.getJobLogs(jobId);
|
||||||
|
return result.logs;
|
||||||
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async queueGetJobs(queueType: typeof QUEUE_TYPES[number], jobTypes: JobType[], search?: string) {
|
public async queueGetJobs(queueType: typeof QUEUE_TYPES[number], jobTypes: JobType[], search?: string) {
|
||||||
const RETURN_LIMIT = 100;
|
const RETURN_LIMIT = 100;
|
||||||
|
|
|
@ -70,6 +70,7 @@ export * as 'admin/queue/inbox-delayed' from './endpoints/admin/queue/inbox-dela
|
||||||
export * as 'admin/queue/retry-job' from './endpoints/admin/queue/retry-job.js';
|
export * as 'admin/queue/retry-job' from './endpoints/admin/queue/retry-job.js';
|
||||||
export * as 'admin/queue/remove-job' from './endpoints/admin/queue/remove-job.js';
|
export * as 'admin/queue/remove-job' from './endpoints/admin/queue/remove-job.js';
|
||||||
export * as 'admin/queue/show-job' from './endpoints/admin/queue/show-job.js';
|
export * as 'admin/queue/show-job' from './endpoints/admin/queue/show-job.js';
|
||||||
|
export * as 'admin/queue/show-job-logs' from './endpoints/admin/queue/show-job-logs.js';
|
||||||
export * as 'admin/queue/promote-jobs' from './endpoints/admin/queue/promote-jobs.js';
|
export * as 'admin/queue/promote-jobs' from './endpoints/admin/queue/promote-jobs.js';
|
||||||
export * as 'admin/queue/jobs' from './endpoints/admin/queue/jobs.js';
|
export * as 'admin/queue/jobs' from './endpoints/admin/queue/jobs.js';
|
||||||
export * as 'admin/queue/stats' from './endpoints/admin/queue/stats.js';
|
export * as 'admin/queue/stats' from './endpoints/admin/queue/stats.js';
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
|
import { QUEUE_TYPES, QueueService } from '@/core/QueueService.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
requireModerator: true,
|
||||||
|
kind: 'read:admin:queue',
|
||||||
|
|
||||||
|
res: {
|
||||||
|
type: 'array',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
items: {
|
||||||
|
optional: false, nullable: false,
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
queue: { type: 'string', enum: QUEUE_TYPES },
|
||||||
|
jobId: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: ['queue', 'jobId'],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||||
|
constructor(
|
||||||
|
private queueService: QueueService,
|
||||||
|
) {
|
||||||
|
super(meta, paramDef, async (ps, me) => {
|
||||||
|
return this.queueService.queueGetJobLogs(ps.queue, ps.jobId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -155,6 +155,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div v-else-if="tab === 'error'" class="_gaps_s">
|
<div v-else-if="tab === 'error'" class="_gaps_s">
|
||||||
<MkCode v-for="log in job.stacktrace" :code="log" lang="stacktrace"/>
|
<MkCode v-for="log in job.stacktrace" :code="log" lang="stacktrace"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else-if="tab === 'logs'">
|
||||||
|
<MkButton primary rounded @click="loadLogs()"><i class="ti ti-refresh"></i> Load logs</MkButton>
|
||||||
|
<div v-for="log in logs">{{ log }}</div>
|
||||||
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -198,6 +202,7 @@ const emit = defineEmits<{
|
||||||
const tab = ref('info');
|
const tab = ref('info');
|
||||||
const editData = ref(JSON5.stringify(props.job.data, null, '\t'));
|
const editData = ref(JSON5.stringify(props.job.data, null, '\t'));
|
||||||
const canEdit = true;
|
const canEdit = true;
|
||||||
|
const logs = ref<string[]>([]);
|
||||||
|
|
||||||
type TlType = TlEvent<{
|
type TlType = TlEvent<{
|
||||||
type: 'created' | 'processed' | 'finished';
|
type: 'created' | 'processed' | 'finished';
|
||||||
|
@ -268,6 +273,10 @@ async function removeJob() {
|
||||||
os.apiWithDialog('admin/queue/remove-job', { queue: props.queueType, jobId: props.job.id });
|
os.apiWithDialog('admin/queue/remove-job', { queue: props.queueType, jobId: props.job.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadLogs() {
|
||||||
|
logs.value = await os.apiWithDialog('admin/queue/show-job-logs', { queue: props.queueType, jobId: props.job.id });
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// function moveJob() {
|
// function moveJob() {
|
||||||
//
|
//
|
||||||
|
|
|
@ -296,6 +296,12 @@ type AdminQueueRemoveJobRequest = operations['admin___queue___remove-job']['requ
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminQueueRetryJobRequest = operations['admin___queue___retry-job']['requestBody']['content']['application/json'];
|
type AdminQueueRetryJobRequest = operations['admin___queue___retry-job']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type AdminQueueShowJobLogsRequest = operations['admin___queue___show-job-logs']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type AdminQueueShowJobLogsResponse = operations['admin___queue___show-job-logs']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminQueueShowJobRequest = operations['admin___queue___show-job']['requestBody']['content']['application/json'];
|
type AdminQueueShowJobRequest = operations['admin___queue___show-job']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -1559,6 +1565,8 @@ declare namespace entities {
|
||||||
AdminQueueRetryJobRequest,
|
AdminQueueRetryJobRequest,
|
||||||
AdminQueueShowJobRequest,
|
AdminQueueShowJobRequest,
|
||||||
AdminQueueShowJobResponse,
|
AdminQueueShowJobResponse,
|
||||||
|
AdminQueueShowJobLogsRequest,
|
||||||
|
AdminQueueShowJobLogsResponse,
|
||||||
AdminQueueStatsResponse,
|
AdminQueueStatsResponse,
|
||||||
AdminRelaysAddRequest,
|
AdminRelaysAddRequest,
|
||||||
AdminRelaysAddResponse,
|
AdminRelaysAddResponse,
|
||||||
|
|
|
@ -713,6 +713,17 @@ declare module '../api.js' {
|
||||||
credential?: string | null,
|
credential?: string | null,
|
||||||
): Promise<SwitchCaseResponseType<E, P>>;
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *Yes* / **Permission**: *read:admin:queue*
|
||||||
|
*/
|
||||||
|
request<E extends 'admin/queue/show-job-logs', P extends Endpoints[E]['req']>(
|
||||||
|
endpoint: E,
|
||||||
|
params: P,
|
||||||
|
credential?: string | null,
|
||||||
|
): Promise<SwitchCaseResponseType<E, P>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No description provided.
|
* No description provided.
|
||||||
*
|
*
|
||||||
|
|
|
@ -88,6 +88,8 @@ import type {
|
||||||
AdminQueueRetryJobRequest,
|
AdminQueueRetryJobRequest,
|
||||||
AdminQueueShowJobRequest,
|
AdminQueueShowJobRequest,
|
||||||
AdminQueueShowJobResponse,
|
AdminQueueShowJobResponse,
|
||||||
|
AdminQueueShowJobLogsRequest,
|
||||||
|
AdminQueueShowJobLogsResponse,
|
||||||
AdminQueueStatsResponse,
|
AdminQueueStatsResponse,
|
||||||
AdminRelaysAddRequest,
|
AdminRelaysAddRequest,
|
||||||
AdminRelaysAddResponse,
|
AdminRelaysAddResponse,
|
||||||
|
@ -717,6 +719,7 @@ export type Endpoints = {
|
||||||
'admin/queue/remove-job': { req: AdminQueueRemoveJobRequest; res: EmptyResponse };
|
'admin/queue/remove-job': { req: AdminQueueRemoveJobRequest; res: EmptyResponse };
|
||||||
'admin/queue/retry-job': { req: AdminQueueRetryJobRequest; res: EmptyResponse };
|
'admin/queue/retry-job': { req: AdminQueueRetryJobRequest; res: EmptyResponse };
|
||||||
'admin/queue/show-job': { req: AdminQueueShowJobRequest; res: AdminQueueShowJobResponse };
|
'admin/queue/show-job': { req: AdminQueueShowJobRequest; res: AdminQueueShowJobResponse };
|
||||||
|
'admin/queue/show-job-logs': { req: AdminQueueShowJobLogsRequest; res: AdminQueueShowJobLogsResponse };
|
||||||
'admin/queue/stats': { req: EmptyRequest; res: AdminQueueStatsResponse };
|
'admin/queue/stats': { req: EmptyRequest; res: AdminQueueStatsResponse };
|
||||||
'admin/relays/add': { req: AdminRelaysAddRequest; res: AdminRelaysAddResponse };
|
'admin/relays/add': { req: AdminRelaysAddRequest; res: AdminRelaysAddResponse };
|
||||||
'admin/relays/list': { req: EmptyRequest; res: AdminRelaysListResponse };
|
'admin/relays/list': { req: EmptyRequest; res: AdminRelaysListResponse };
|
||||||
|
|
|
@ -91,6 +91,8 @@ export type AdminQueueRemoveJobRequest = operations['admin___queue___remove-job'
|
||||||
export type AdminQueueRetryJobRequest = operations['admin___queue___retry-job']['requestBody']['content']['application/json'];
|
export type AdminQueueRetryJobRequest = operations['admin___queue___retry-job']['requestBody']['content']['application/json'];
|
||||||
export type AdminQueueShowJobRequest = operations['admin___queue___show-job']['requestBody']['content']['application/json'];
|
export type AdminQueueShowJobRequest = operations['admin___queue___show-job']['requestBody']['content']['application/json'];
|
||||||
export type AdminQueueShowJobResponse = operations['admin___queue___show-job']['responses']['200']['content']['application/json'];
|
export type AdminQueueShowJobResponse = operations['admin___queue___show-job']['responses']['200']['content']['application/json'];
|
||||||
|
export type AdminQueueShowJobLogsRequest = operations['admin___queue___show-job-logs']['requestBody']['content']['application/json'];
|
||||||
|
export type AdminQueueShowJobLogsResponse = operations['admin___queue___show-job-logs']['responses']['200']['content']['application/json'];
|
||||||
export type AdminQueueStatsResponse = operations['admin___queue___stats']['responses']['200']['content']['application/json'];
|
export type AdminQueueStatsResponse = operations['admin___queue___stats']['responses']['200']['content']['application/json'];
|
||||||
export type AdminRelaysAddRequest = operations['admin___relays___add']['requestBody']['content']['application/json'];
|
export type AdminRelaysAddRequest = operations['admin___relays___add']['requestBody']['content']['application/json'];
|
||||||
export type AdminRelaysAddResponse = operations['admin___relays___add']['responses']['200']['content']['application/json'];
|
export type AdminRelaysAddResponse = operations['admin___relays___add']['responses']['200']['content']['application/json'];
|
||||||
|
|
|
@ -584,6 +584,15 @@ export type paths = {
|
||||||
*/
|
*/
|
||||||
post: operations['admin___queue___show-job'];
|
post: operations['admin___queue___show-job'];
|
||||||
};
|
};
|
||||||
|
'/admin/queue/show-job-logs': {
|
||||||
|
/**
|
||||||
|
* admin/queue/show-job-logs
|
||||||
|
* @description No description provided.
|
||||||
|
*
|
||||||
|
* **Credential required**: *Yes* / **Permission**: *read:admin:queue*
|
||||||
|
*/
|
||||||
|
post: operations['admin___queue___show-job-logs'];
|
||||||
|
};
|
||||||
'/admin/queue/stats': {
|
'/admin/queue/stats': {
|
||||||
/**
|
/**
|
||||||
* admin/queue/stats
|
* admin/queue/stats
|
||||||
|
@ -10167,6 +10176,73 @@ export interface operations {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
'admin___queue___show-job-logs': {
|
||||||
|
requestBody: {
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
/** @enum {string} */
|
||||||
|
queue: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver';
|
||||||
|
jobId: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
responses: {
|
||||||
|
/** @description OK (with results) */
|
||||||
|
200: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
'application/json': string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description Client error */
|
||||||
|
400: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description Authentication error */
|
||||||
|
401: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description Forbidden error */
|
||||||
|
403: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description I'm Ai */
|
||||||
|
418: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/** @description Internal server error */
|
||||||
|
500: {
|
||||||
|
headers: {
|
||||||
|
[name: string]: unknown;
|
||||||
|
};
|
||||||
|
content: {
|
||||||
|
'application/json': components['schemas']['Error'];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
admin___queue___stats: {
|
admin___queue___stats: {
|
||||||
responses: {
|
responses: {
|
||||||
/** @description OK (with results) */
|
/** @description OK (with results) */
|
||||||
|
|
Loading…
Reference in New Issue