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개의 좋아요