private void Tick() { if (CheckTickCondition() == false) { return; } Boolean workThisTick = false; // ConcurrentQueue지만 락을 사용한다. // 락을 사용하지 않고 여러 스레드가 큐에서 로그를 가져가면, 배치 안의 로그 수가 줄어들어 효율이 떨어진다. // 다른 스레드에서의 Push는 큐 뒤에 쌓이므로 상관없다. // 다른 스레드에서의 Pop은 강제로 큐를 비우는 경우에 발생할 수 있다(팝하고 개수가 0보다 큰지 확인). lock (_tickLock) { _threadLocalStopwatch.Value.Restart(); Int64 nowMS = Now.TimestampMS(); if (IsLongTimePut(nowMS)) { UpdateLastWorkTime(nowMS); // 로그가 충분하지 않을수도 있지만 보낸지 오래 되었으므로 모인 것을 보낸다. Int32 popCount = CalculatePopCount(); workThisTick = 0 < ClearAndPopLogToThreadLocal(popCount); } else { workThisTick = TryPopLogToThreadLocal(); if (workThisTick) { UpdateLastWorkTime(nowMS); } } _threadLocalStopwatch.Value.Stop(); } if (workThisTick) { ProcessThreadLocal(); } }
private void StartImpl() { lock (_lock) { if (Config == null) { throw new LoggerStartException(StartResultType.InvalidConfig); } if (State != StateType.Stop) { throw new LoggerStartException(StartResultType.NotStopped); } State = StateType.Starting; StartTime = DateTime.UtcNow; GenerateInstanceID(); CreateLoggerParts(); CreateLoggerComponents(); InitializeLoggerComponents(); StartLoggerComponents(); CreateAndStartLoggerThread(); _lastWorkTimeMS = Now.TimestampMS(StartTime); State = StateType.Start; } Reporter.Fatal("*Start Logger!*\n" + $"Assembly Version: `{Config.AssemblyVersion}`\n" + $"Build: `{BuildType}`\n" + $"InstanceID: `{InstanceID}`\n" + $"```Config\n{Config.ConfigStringPretty}```"); }