feat: Implement smart factory log functionality
- Added a new controller for managing smart factory logs, including retrieval and statistics endpoints. - Integrated smart factory log migration to set up the necessary database structure. - Enhanced the authentication controller to include user name in log submissions. - Developed a frontend page for displaying and filtering smart factory logs, accessible only to super admins. - Implemented API calls for fetching logs and statistics, improving data visibility and management. These changes aim to provide comprehensive logging capabilities for smart factory activities, enhancing monitoring and analysis for administrators.
This commit is contained in:
@@ -3,20 +3,26 @@
|
||||
|
||||
import axios from "axios";
|
||||
import { logger } from "./logger";
|
||||
import { query } from "../database/db";
|
||||
|
||||
const SMART_FACTORY_LOG_URL =
|
||||
"https://log.smart-factory.kr/apisvc/sendLogDataJSON.do";
|
||||
|
||||
/**
|
||||
* 스마트공장 활용 로그 전송
|
||||
* 스마트공장 활용 로그 전송 + DB 저장
|
||||
* 로그인 성공 시 비동기로 호출하여 응답을 블로킹하지 않음
|
||||
*/
|
||||
export async function sendSmartFactoryLog(params: {
|
||||
userId: string;
|
||||
userName?: string;
|
||||
remoteAddr: string;
|
||||
useType?: string;
|
||||
companyCode?: string;
|
||||
}): Promise<void> {
|
||||
const now = new Date();
|
||||
const logDt = formatDateTime(now);
|
||||
const useType = params.useType || "접속";
|
||||
|
||||
// 회사별 키 우선 조회, 없으면 공통 키 폴백
|
||||
const apiKey = (params.companyCode && process.env[`SMART_FACTORY_API_KEY_${params.companyCode}`])
|
||||
|| process.env.SMART_FACTORY_API_KEY;
|
||||
@@ -25,17 +31,26 @@ export async function sendSmartFactoryLog(params: {
|
||||
logger.warn(
|
||||
"SMART_FACTORY_API_KEY 환경변수가 설정되지 않아 스마트공장 로그 전송을 건너뜁니다."
|
||||
);
|
||||
// SKIPPED 상태로 DB 기록
|
||||
await saveLog({
|
||||
companyCode: params.companyCode || "",
|
||||
userId: params.userId,
|
||||
userName: params.userName,
|
||||
useType,
|
||||
connectIp: params.remoteAddr,
|
||||
sendStatus: "SKIPPED",
|
||||
responseStatus: null,
|
||||
errorMessage: "API 키 미설정",
|
||||
logDt: now,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const now = new Date();
|
||||
const logDt = formatDateTime(now);
|
||||
|
||||
const logData = {
|
||||
crtfcKey: apiKey,
|
||||
logDt,
|
||||
useSe: params.useType || "접속",
|
||||
useSe: useType,
|
||||
sysUser: params.userId,
|
||||
conectIp: params.remoteAddr,
|
||||
dataUsgqty: "",
|
||||
@@ -52,11 +67,76 @@ export async function sendSmartFactoryLog(params: {
|
||||
userId: params.userId,
|
||||
status: response.status,
|
||||
});
|
||||
|
||||
// SUCCESS 상태로 DB 기록
|
||||
await saveLog({
|
||||
companyCode: params.companyCode || "",
|
||||
userId: params.userId,
|
||||
userName: params.userName,
|
||||
useType,
|
||||
connectIp: params.remoteAddr,
|
||||
sendStatus: "SUCCESS",
|
||||
responseStatus: response.status,
|
||||
errorMessage: null,
|
||||
logDt: now,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : String(error);
|
||||
// 스마트공장 로그 전송 실패해도 로그인에 영향 없도록 에러만 기록
|
||||
logger.error("스마트공장 로그 전송 실패", {
|
||||
userId: params.userId,
|
||||
error: error instanceof Error ? error.message : error,
|
||||
error: errorMsg,
|
||||
});
|
||||
|
||||
// FAIL 상태로 DB 기록
|
||||
await saveLog({
|
||||
companyCode: params.companyCode || "",
|
||||
userId: params.userId,
|
||||
userName: params.userName,
|
||||
useType,
|
||||
connectIp: params.remoteAddr,
|
||||
sendStatus: "FAIL",
|
||||
responseStatus: null,
|
||||
errorMessage: errorMsg,
|
||||
logDt: now,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** DB에 로그 저장 */
|
||||
async function saveLog(params: {
|
||||
companyCode: string;
|
||||
userId: string;
|
||||
userName?: string;
|
||||
useType: string;
|
||||
connectIp: string;
|
||||
sendStatus: string;
|
||||
responseStatus: number | null;
|
||||
errorMessage: string | null;
|
||||
logDt: Date;
|
||||
}): Promise<void> {
|
||||
try {
|
||||
await query(
|
||||
`INSERT INTO smart_factory_log
|
||||
(company_code, user_id, user_name, use_type, connect_ip, send_status, response_status, error_message, log_dt)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
||||
[
|
||||
params.companyCode,
|
||||
params.userId,
|
||||
params.userName || null,
|
||||
params.useType,
|
||||
params.connectIp,
|
||||
params.sendStatus,
|
||||
params.responseStatus,
|
||||
params.errorMessage,
|
||||
params.logDt,
|
||||
]
|
||||
);
|
||||
} catch (dbError) {
|
||||
// DB 저장 실패해도 로그인 프로세스에 영향 없도록
|
||||
logger.error("스마트공장 로그 DB 저장 실패", {
|
||||
userId: params.userId,
|
||||
error: dbError instanceof Error ? dbError.message : dbError,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user