🐳

.Net Core2.2におけるWebAPIのログ出力について

2024/12/31に公開

.NET Coreを始めたのですが、理解が浅かったのでこまめにまとめたいと思います。
ここではWebAPIによるプロジェクトのログ出力についてまとめます。

環境

Tools Version
.NET Core SDK 2.2.401

初めに

.NET CoreにおけるLoggerの基本的な使い方はDIによる利用になります。

    [Route("api/[action]")]
    [ApiController]
    public class SamplesController : ControllerBase
    {
        private readonly ILogger<SamplesController> _logger;
        public SamplesController(ILogger<SamplesController> logger)
        {
            _logger = logger;
        }
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Sample>>> GetSamples()
        {
            _logger.LogTrace("trace");
            _logger.LogDebug("debug");
            _logger.LogInformation("info");
            _logger.LogWarning("warning");
            _logger.LogError("error");
            _logger.LogCritical("critical");
            return new List<Sample> { new Sample() };
        }
    }

TraceIdの扱いをどうするか

例えば、GET: api/samples/{id}のようなエンドポイントを考えます。
以下のようなコードを用意します。

    [Route("api/[action]")]
    [ApiController]
    public class SamplesController : ControllerBase
    {
        private readonly ISampleService _sampleService;
        private readonly ILogger<SamplesController> _logger;
        public SamplesController(ISampleService sampleService, ILogger<SamplesController> logger)
        {
            _sampleService = sampleService;
            _logger = logger;
        }
        [HttpGet("{id}")]
        public async Task<ActionResult<Sample>> GetSample(int id)
        {
          var sample = await _sampleService.FindById(id);
          if (sample == null) {
            return NotFound();
          }
          return  sample;
        }
    }

指定したIdが存在しない場合、NotFoundResultを返します。

この時のレスポンスは以下のようになります。


    {
        "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
        "title": "Not Found",
        "status": 404,
        "traceId": "0HLOJ3836502B:00000001"
    }

ここで気になるのはtraceIdの存在です。ログの出力をDebugレベルで確認すると、リクエストの開始とレスポンスの完了のタイミングでtraceIdの出力があります。しかし、Debugレベルでの出力になるので、不要なのでは?と思ってしまいます。

悩んだ結果、TraceIdをログに出すことにしました。

        [HttpGet("{id}")]
        public async Task<ActionResult<Sample>> GetSample(int id)
        {
          var sample = await _sampleService.FindById(id);
          if (sample == null) {
            _logger.LogError($"traceId: {HttpContext.TraceIdentifier}. Sample is not found.");
            return NotFound();
          }
          return  sample;
        }

Controllerからであれば、HttpContextプロパティのTraceIdentifierをログ出力すれば良いです。

最後に

そもそもレスポンスをtraceIdを返さないようにすることもできるんですが、どちらがいいんでしょうか 🤔

参考

Discussion