CA2254 문의드립니다.

  • 무엇을 하고자 하는지
    이 경고가 나오는 이유를 알고 싶어요.
  • 현재 작성한 코드 중 문제가 되는 부분
    private readonly ILogger _logger;
    _logger.LogInformation(msg);
  • 기대하는 동작
    경고가 나와서 없애고 싶어요.

.net6로 변경 한 후에 나오는 경고인 것 같습니다. 답변 부탁드립니다.

좋아요 1

.NET 6에 도입된 분석기에 의한 경고로 보여집니다. 제가 직접 코드로 테스트해보지는 않았지만 이유는 다음과 같습니다.

  • .NET 에서는 로깅시 부하를 줄이기 위해 컴파일 타임 때 로그 메시지를 해석합니다
  • 이때 메시지가 메시지템플릿(첫번째 인자)가 정적 문자열로 해석되지 않으면 해당 경고를 발생합니다. 이는 로깅 중에 예외가 발생하는 경우를 없애고 로깅 성능을 개선합니다.
  • CA2254는 분석기 오류이므로 실제 동작하는데 문제는 없습니다. 해당 경고를 끄셔도 됩니다.
  • 또는 LogInformation("{msg}", msg) 형태로 바꾸실 수 있습니다.

추가: 잘못된 정보가 있어 내용을 수정하였습니다.

좋아요 3

답변 감사드립니다. 덕분에 의문점이 많이 해결되었습니다.
정적 문자열로 해석된다는 의미를 이해하기 좀 어려운데요, 어떤 부분을 공부해야 할까요?

좋아요 1

제가 다른 내용도 적으면서 약간의 혼돈을 드린것 같습니다. 먼저 정적 문자열은 말그대로 변하지 않는 값. 상수의 의미로 "메시지 템플릿"을 그렇게 표현했습니다. LogInformation()을 사용하기 위한 첫번째 템플릿 문자열을 사용할 때 실수를 막기 위함입니다. 그러므로 그정도로 이해하시면 되고요, 그렇기 때문에 템플릿 문자열의 인자 대로 인자를 적지 않으면 마찬가지로 경고 메시지가 뜰 것으로 보입니다. – 이부분은 제가 직접 확인해보지는 않았습니다.

좋아요 2

직접 확인해 봤습니다. 아래의 코드드와 발생하는 경고, 정보를 확인하시면 도움이 되지 않을까 합니다.

    public class IndexModel : PageModel
    {
        private const string LogMessage = "{}: {}";

        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;

            _logger.LogInformation($"{_logger}"); // CA2254
            var msg = "1234";
            _logger.LogInformation(msg); // CA2254
            _logger.LogInformation("{0}", msg); // CA2253 - 자리 표시자는 숫자로만 구성되어서는 안됨
            _logger.LogInformation("{}", msg);
            _logger.LogInformation("{Msg}", msg);
            _logger.LogInformation(LogMessage, "value", 40);
            _logger.LogInformation(LogMessage, "value"); // 오류인데 잡지 못함
            _logger.LogInformation(LogMessage); // CA2017 - 매개 변수수가 자리 표시자의 수와 일치하지 않음
            _logger.LogInformation(LogMessage, "value", 40, 50); // CA2017 - 매개 변수수가 자리 표시자의 수와 일치하지 않음
            _logger.LogInformation($"{nameof(IndexModel)}: {{}} {{}}", "value", 40);
        }

        public void OnGet()
        {
        }
    }
좋아요 2

위에 컴파일 타임 때의 동작은 C# 10부터 사용 가능한 보간 문자열을 효과적으로 처리하기 위한 InterpolatedStringHandler의 내용으로 확인해보니 Logger에 적용되어 있지 않았습니다. 해서 관련 내용은 잘못된 정보입니다.

좋아요 2

감사드립니다. 첫번째 인자를 상수로 전달하지 않아서 생기는 경고였네요.

로깅 메시지 템플릿은 LoggerExtensions.LogInformation(ILogger, string?, params object?[])에 대한 호출 간에 달라지지 않아야 합니다.

메시지가 이렇게 나와서 의미를 이해하기는 참 어려웠거든요.

좋아요 2

직접 확인까지 해 주셔서 정말 감사드립니다. 전 이게 제일 좋은 것 같습니다. msg.c_str()이런 함수가 있었으면 소스가 더 명시적이지 않을까 생각해 봅니다. ㅋ

좋아요 2