콘텐츠로 이동
무료 평가 시작

시간 초과와 진단

클라이언트 옵션의 timeout_ms(1~300000 ms)는 두 가지에 적용됩니다.

  • 탐색, 연결, 세션 활성화, 종료의 네트워크 교환 하나하나
  • pdcomm_opcua_client_begin으로 보낸 요청 하나하나. 이 시간 안에 응답이 와야 합니다.

기본값은 C pdcomm_opcua_client_options_init과 .NET ClientOptions가 10000 ms, Qt·MFC 작업자가 5000 ms입니다. C 예제는 --timeout으로 바꿉니다.

연결을 받은 뒤 아무 응답도 보내지 않는 서버에 1000 ms로 접속하면 1초 뒤 다음 오류가 납니다.

Error: discover failed (SDK status 5): OPC UA timeout

요청이 제한 시간을 넘기면 다음 pdcomm_opcua_client_poll이 실패하고 연결이 닫힙니다. 그 뒤의 호출은 PDCOMM_OPCUA_CLOSED를 돌려줍니다. 핸들을 해제하고 다시 연결합니다. Publish 요청은 게시 주기나 keep-alive 주기만큼 늦게 응답하므로, 구독을 쓸 때는 제한 시간을 keep-alive 주기보다 길게 잡습니다.

서버가 응답 하나를 중단(abort chunk)하면 그 요청만 PDCOMM_OPCUA_RUNTIME_ERROR로 끝나고 연결은 유지됩니다. 오류 문장에 서버가 보낸 StatusCode가 들어 있습니다.

시뮬레이터 클라이언트의 client.timeout_ms(100~60000 ms, 기본 5000)가 같은 역할을 합니다. 요청이 제한 시간을 넘기면 시뮬레이터는 연결을 닫고 다음 오류를 돌려줍니다.

{"error":"Timeout (client connection closed)","ok":false}

Simulator.Delay 메서드로 느린 응답을 재현할 수 있습니다. 제한 시간을 1000 ms로 설정하고 3000 ms를 기다리게 하면 1초 뒤 위 오류가 납니다.

{"action":"configure","config":{"client":{"timeout_ms":1000}}}
{"action":"call","method":"ns=2;s=Simulator.Delay","arguments":[{"type":"UInt32","value":3000}]}

Simulator.Delay는 시뮬레이터 서버의 처리 스레드를 그 시간 동안 멈춥니다. 그동안 새 연결도 처리되지 않으므로, 바로 connect를 다시 보내면 Timeout이 날 수 있습니다. 대기 시간이 지난 뒤 다시 연결합니다.

방법 동작
헤드리스 {"action":"cancel"} 실행 중인 동작이 Cancelled로 끝납니다.
GUI Cancel request 같은 취소를 요청합니다.
MCP notifications/cancelled 해당 요청을 중단하고 응답하지 않습니다.

취소는 시뮬레이터 클라이언트가 응답을 기다리는 것을 멈출 뿐, 서버에 이미 보낸 요청을 되돌리지 않습니다. 나중에 도착한 응답은 시뮬레이터가 버립니다. state의 client.pending_cancelled가 아직 버리지 못한 응답 수입니다.

SDK. 실패한 함수 바로 뒤에 같은 스레드에서 pdcomm_opcua_last_error_copy로 오류 문장을 읽습니다. C++의 pdcomm::opcua::error::what(), .NET의 OpcUaException.Message가 같은 문장입니다. 응답의 서비스 결과는 pdcomm_opcua_response_get_info의 service_status, 응답 종류는 binary_id로 확인합니다. binary_id가 397이면 ServiceFault입니다. SDK 라이브러리는 로그 파일을 쓰지 않습니다.

시뮬레이터 동작 기록. {"action":"trace"} 또는 GUI의 Trace & Diagnostics 탭은 최근 동작 1000개를 보여 줍니다. 항목마다 작업 공간, 동작, 성공 여부, 걸린 시간(마이크로초), 대상 노드, 오류 문장이 있습니다.

{"action":"call","elapsed_us":210145,"error":"Cancelled","ok":false,"sequence":3,"time_ms":412,"workspace":"read_write_methods"}

서버 감사 기록. {"action":"server_status"}의 audit에 시뮬레이터 서버의 보안 채널, 세션, 사용자 인증 기록이 최근 100개까지 남습니다.

{"action":"user authentication rejected","channel":3,"status":"BadUserAccessDenied (0x801F0000)"}

시뮬레이터 프로그램(GUI, 헤드리스, MCP)은 진단 로그를 JSON 줄 형식으로 씁니다. 기본으로 꺼져 있습니다.

동작으로 켜기. logging_configure에 설정을 넘깁니다. GUI에서는 Trace & Diagnostics 탭의 **Diagnostic log (off by default)**와 Apply logging을 씁니다.

{"action":"logging_configure","config":{"enabled":true,"level":"debug","file":"logs/opcua-simulator.jsonl"}}
필드 기본값 설명
enabled true 로그를 쓸지 여부
level info error, warn, info, debug, trace
file 없음 로그 파일. 없으면 표준 오류로 씁니다. 폴더는 미리 있어야 합니다.
max_bytes 10485760 이 크기를 넘으면 파일을 바꿉니다.
files 3 보관할 파일 수(1~16)
forensics false 1초마다 프로세스 상태를 기록합니다. debug 이상에서만 켤 수 있습니다.

환경 변수로 켜기. 프로그램을 시작할 때부터 기록하려면 환경 변수를 씁니다.

터미널 창
mkdir -p logs
PDCOMM_LOG=debug PDCOMM_LOG_FILE=logs/opcua-simulator.jsonl "$OPCUA_APPS/bin/pdcomm-opcua-headless"

PDCOMM_LOG(수준), PDCOMM_LOG_FILE, PDCOMM_LOG_MAX_BYTES, PDCOMM_LOG_FILES, PDCOMM_LOG_FORENSICS를 지원합니다.

기록 한 줄은 다음과 같습니다. 실패한 동작은 error 수준으로 남습니다.

{"arch":"aarch64","build_id":"4115d51b3c0114ac8ea1edc0786f07c726b87d8a","component":"service","event":"action_completed","fields":{"action":"connect","elapsed_us":5,"error_code":"ServiceError","success":false},"instance_id":"94497-1791998764824784000","level":"error","monotonic_us":197102,"os":"macos","pid":94497,"protocol":"opcua","request_id":7,"schema_version":1,"sdk_version":"0.1.0","sequence":8,"thread":"ThreadId(1)","timestamp_unix_ms":1791998765021}

로그에는 동작 이름, 성공 여부, 오류 분류(Timeout, Cancelled, ServiceError), 걸린 시간이 남습니다. 노드 값, 암호, 개인 키는 남지 않습니다. {"action":"logging_status"}는 쓴 기록 수(written), 버린 기록 수(dropped), 쓰기 오류 수를 보여 주고, {"action":"logging_flush"}는 버퍼를 파일에 씁니다.

응답 원인과 조치
Cannot open logging sink 로그 파일의 폴더가 없거나 쓸 수 없습니다. 폴더를 만듭니다.
Invalid logging level level 값이 틀렸습니다.
Forensics requires debug or trace logging forensics는 debug나 trace 수준에서만 켭니다.

문제를 문의할 때는 재현 순서, 오류 문장, 동작 기록, 진단 로그 파일을 함께 보내 주십시오. 로그에는 암호가 남지 않지만, 보내기 전에 파일 경로 같은 내용을 확인합니다.