본문 바로가기
[(주)북스 | 이노소프트]/SW개발정보

C# 설비 알람 로그 CSV 만들기: 필드 이스케이프와 엑셀 수식 위험 점검

by BOOX 2026. 10. 18.

설비 알람 로그를 CSV로 저장해 엑셀에서 열었는데 열이 밀리거나 한 셀에 여러 줄이 들어간 적 있으신가요? 알람 메시지에 쉼표, 큰따옴표, 줄바꿈이 있으면 단순히 문자열을 콤마로 연결한 파일은 쉽게 깨집니다.

 

오늘은 C#에서 설비 이벤트 로그 한 행을 안전하게 만드는 기본 구조를 살펴봅니다. CSV 문법에 맞춘 따옴표 처리는 스프레드시트 수식 실행 위험을 해결하지 않으므로 두 문제를 따로 다루겠습니다.

 

먼저 로그 필드를 고정하세요

현장 추적에 필요한 최소 필드를 먼저 정합니다. 예를 들어 이벤트 발생 시각(UTC), 장치 ID, 알람 코드, 메시지, 상태 값과 단위를 기록할 수 있습니다. 모든 행에 같은 순서와 필드 수를 유지하고, 헤더를 함께 저장하세요. 비밀번호, 인증 토큰, 불필요한 개인정보는 로그에 넣지 않습니다.

 

시간은 시스템 지역 설정에 따라 모양이 바뀌는 짧은 날짜 문자열보다 오프셋이 포함된 일관된 형식을 쓰는 편이 여러 PC의 기록을 비교하기 쉽습니다. 예제는 UTC 시각을 ISO 8601 왕복 형식으로 저장합니다. 장비 PC의 시계 동기화 상태도 함께 확인하세요.

 

C# CSV 필드 이스케이프 예제

RFC 4180은 필드 안에 콤마, 큰따옴표, 줄바꿈이 있으면 필드를 큰따옴표로 감싸고, 필드 내부 큰따옴표는 두 번 써서 표현하는 방식을 설명합니다.

 

private static string CsvField(string? value)

{

    value ??= string.Empty;

    char quote = (char)34;

    return new string(quote, 1) + value.Replace(new string(quote, 1), new string(quote, 2)) + new string(quote, 1);

}

 

string row = string.Join(",",

    CsvField(DateTimeOffset.UtcNow.ToString("O")),

    CsvField(deviceId),

    CsvField(alarmCode),

    CsvField(message));

 

예를 들어 메시지가 압력, "상한"이면 CSV 안에서는 "압력, ""상한"""처럼 한 필드로 감쌉니다. 이 메서드는 CSV 구분자와 따옴표를 처리하는 예시이지 파일 저장 전체 구현이나 보안 검증이 아닙니다. 프로젝트의 C# 버전과 CSV 소비 프로그램에 맞춰 테스트하세요.

 

엑셀에서 열 때의 별도 보안 주의

CSV 따옴표 이스케이프는 필드 경계를 지키는 문법입니다. 셀 값이 =, +, -, @ 같은 문자로 시작하면 Excel이나 다른 스프레드시트가 이를 수식으로 해석할 가능성이 있어, 장비 메시지나 외부 입력을 사람이 CSV로 열 때는 CSV 수식 주입을 별도로 검토해야 합니다.

 

원본 감사 로그는 변경하지 않고 보존하고, 스프레드시트로 배포할 내보내기본에는 사용 목적과 대상 프로그램에 맞는 별도 처리 정책을 두세요. OWASP는 앱별 동작 차이와 Excel에서 저장 후 다시 열 때 처리 방식이 달라질 수 있음을 경고합니다. 모든 프로그램에 통하는 단일 정화 규칙이 있다고 가정하지 말고 실제로 사용하는 Excel/LibreOffice 버전에서 테스트하세요.

 

운영 현장 체크리스트

□ 헤더와 각 레코드의 열 순서·개수가 고정되어 있는가

□ 콤마, 따옴표, 한글, CR/LF, 빈 값으로 파싱 테스트했는가

□ 발생 시각의 기준(UTC 또는 오프셋)과 장비 시계 동기화를 기록했는가

□ 동시 이벤트는 단일 writer나 큐로 직렬화하고, 파일 보관 기간·용량을 정했는가

□ 외부 입력이 섞인 CSV를 스프레드시트에서 열 때 수식 주입 위험을 확인했는가

 

알람 로그는 단순한 텍스트 파일이 아니라 장애 발생 시 원인과 순서를 재구성하는 자료입니다. CSV 문법, 시간 기준, 파일 보관, 내보내기 보안을 각각 점검하고 실제 운영 전에 샘플 데이터를 여러 프로그램에서 읽어 보세요. 이 예제는 로그 형식 교육용이며 장치 제어나 출력 신호를 실행하지 않습니다.

 

관련 글: WinForms 통신 중 화면 멈춤 방지와 async·await: https://innosoft.tistory.com/51

 

C# WinForms 설비 통신 중 화면 멈춤 방지: async·await와 취소 처리

설비 제어 프로그램에서 PLC나 장치 응답을 기다리는 동안 버튼과 화면이 멈춰 보인다면, 통신 작업이 UI 스레드를 점유하는지 먼저 확인해 보세요. 단순히 작업을 백그라운드로 옮기는 것보다,

www.innosoft.kr

 

참고 자료

RFC Editor, RFC 4180, Common Format and MIME Type for CSV Files (2005-10): https://www.rfc-editor.org/info/rfc4180

 

RFC 4180: Common Format and MIME Type for Comma-Separated Values (CSV) Files | RFC Editor

This RFC documents the format used for Comma-Separated Values (CSV) files and registers the associated MIME type "text/csv". This memo provides information for the Internet community.

www.rfc-editor.org

OWASP, CSV Injection (확인일 2026-10-18): https://community.owasp.org/attacks/CSV_Injection

 

CSV Injection | OWASP Foundation

CSV Injection on the main website for The OWASP Foundation. OWASP is a nonprofit foundation that works to improve the security of software.

community.owasp.org

Microsoft Learn, Standard date and time format strings, round-trip “O” format (확인일 2026-10-18): https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings#the-round-trip-o-o-format-specifier

 

Standard date and time format strings - .NET

Learn how to use a standard date and time format string to define the text representation of a date and time value in .NET.

learn.microsoft.com

 

이미지 출처: David Lippincott / Chassis Plans, “Industrial-computer.jpg” (2012), Wikimedia Commons, CC BY 3.0. 일반 산업용 PC 사진으로 이노소프트 제품이나 로그 화면이 아닙니다. 라이선스: https://creativecommons.org/licenses/by/3.0/ 원본: https://commons.wikimedia.org/wiki/File:Industrial-computer.jpg

 

설비제어 프로그램의 데이터 기록이나 C# 교육·개발 정보를 찾으신다면 이노소프트 홈페이지도 확인해 보세요: www.innosoft.kr

설비 데이터 기록용 산업용 PC 내부 모습. 이노소프트 제품 사진은 아님.