Skip to content

tail -f garbled output when log has Korean characters #1693

Open

Description

@Jamongss

개요

  • python3.10 / supervisor-4.2.5 기준
  • supervisor tail -f 입력 시 한글이 깨지는 예외 처리
  • supervisor> tail -f service_name 명령어로 실시간 로그 출력 시 기존에 찍힌 문자를 불러오는 과정에서 인코딩/디코딩 로직 예외 발생 -> 한글이 깨져서 출력 됨
  • 기존 문자를 읽어올 때만 깨져서 보이고 커맨드 입력 시점 이후 터미널에 찍히는 실시간 로그는 정상으로 출력 됨

원인

  • tail -f 입력 시 설정된 초기 head 길이로 byte를 읽어올 때 한글이 잘리면서 깨진 문자열을 그대로 출력(설정된 head 값보다 적은 양의 로그를 불러올 때는 깨짐 현상 없음)
  • 맨 앞 잘린 문자열만 깨져 보여야 하지만 이후 나머지 문자열도 모두 깨져서 출력 됨
  • 실시간으로 찍히는 로그는 정상 출력 됨
  • decode 처리하는 부분에서 예외 처리가 되지 않음

수정 내용

  • compat.py

AS-IS

  - 54 line: return s.encode(encoding)
  - 60 line: return s.decode(encoding)

TO-BE

  - 54 line: return s.encode(encoding, errors='replace')
  - 60 line: return s.decode(encoding, errors='replace')

수정 후

  • 인입된 bytes에서 깨진 부분은 '�'로 표시하고 나머지 부분은 정상적으로 decode 진행
  • 깨진 문자를 대체 문자(�)로 표시하여 처리 연속성 보장
  • 잘못된 인코딩이나 깨진 바이트 데이터로 인한 UnicodeDecodeError/UnicodeEncodeError
    예외 방지

Activity

  1. changed the title [-]Improve encoding/decoding error handling in compat.py[/-] [+]compat.py - 한글 인코딩/디코딩 에러 예외처리[/+] on Aug 25, 2025
  2. Jamongss commented on Aug 25, 2025

    @Jamongss
    Author

    [ENG]

    Summary

    • Environment: Python 3.10 / Supervisor 4.2.5
    • When running supervisorctl tail -f, Korean characters are displayed as garbled text due to missing error handling in encoding/decoding.
    • Specifically, with the command supervisorctl> tail -f service_name, previously written log messages are corrupted when being read back, while new logs printed after the command runs are displayed correctly.

    Root Cause

    • When tail -f is executed, the initial portion of the log (head length) is read as bytes.
    • If a multibyte Korean character is cut in the middle, decoding fails and the corrupted string is printed as-is.
    • This corruption spreads: not only the truncated first character but also the rest of the string is displayed incorrectly.
    • Newly appended log lines are streamed and displayed correctly.
    • The decode logic does not handle errors, leading to UnicodeDecodeError or broken text output.

    Modification

    • File: compat.py

    AS-IS

      - 54 line: return s.encode(encoding)
      - 60 line: return s.decode(encoding)
    

    TO-BE

      - 54 line: return s.encode(encoding, errors='replace')
      - 60 line: return s.decode(encoding, errors='replace')
    

    After the Fix

    • When invalid bytes are encountered, they are replaced with the Unicode replacement character �, while the rest of the string is decoded correctly.
    • Ensures continuity of log output by gracefully handling corrupted sequences.
    • Prevents UnicodeDecodeError / UnicodeEncodeError caused by malformed encoding or truncated multibyte characters.
  3. changed the title [-]compat.py - 한글 인코딩/디코딩 에러 예외처리[/-] [+]tail -f garbled output when log has Korean characters[/+] on Aug 25, 2025
  4. mnaberez commented on Aug 26, 2025

    @mnaberez
    Member

    Patch suggested above and in #1694:

    diff --git a/supervisor/compat.py b/supervisor/compat.py
    index e741f47fb..596727173 100644
    --- a/supervisor/compat.py
    +++ b/supervisor/compat.py
    @@ -51,13 +51,14 @@ def as_bytes(s, encoding='utf8'):
             if isinstance(s, bytes):
                 return s
             else:
    -            return s.encode(encoding)
    +            return s.encode(encoding, errors='replace')
     
         def as_string(s, encoding='utf8'):
             if isinstance(s, str):
                 return s
             else:
    -            return s.decode(encoding)
    +            # 인입된 bytes에서 깨진 부분은 '�'로 표시하고 나머지 부분은 계속 decode 진행
    +            return s.decode(encoding, errors='replace')
     
         def is_text_stream(stream):
             import _io
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions