Beispiel #1
0
        public void WriteTrace(Span[] trace)
        {
            if (_serializationTask.IsCompleted)
            {
                // Serialization thread is not running, serialize the trace in the current thread
                SerializeTrace(trace);
            }
            else
            {
                _pendingTraces.Enqueue(new WorkItem(trace));

                if (!_serializationMutex.IsSet)
                {
                    _serializationMutex.Set();
                }
            }

            if (_statsd != null)
            {
                _statsd.Increment(TracerMetricNames.Queue.EnqueuedTraces);
                _statsd.Increment(TracerMetricNames.Queue.EnqueuedSpans, trace.Length);
            }
        }
        public void Refresh()
        {
            if (!_fullInstanceName)
            {
                _instanceName = GetSimpleInstanceName();
            }

            TryUpdateGauge(MetricsNames.Gen0HeapSize, _gen0Size);
            TryUpdateGauge(MetricsNames.Gen1HeapSize, _gen1Size);
            TryUpdateGauge(MetricsNames.Gen2HeapSize, _gen2Size);
            TryUpdateGauge(MetricsNames.LohSize, _lohSize);

            TryUpdateCounter(MetricsNames.ContentionCount, _contentionCount, ref _lastContentionCount);

            var gen0 = GC.CollectionCount(0);
            var gen1 = GC.CollectionCount(1);
            var gen2 = GC.CollectionCount(2);

            if (_previousGen0Count != null)
            {
                _statsd.Increment(MetricsNames.Gen0CollectionsCount, gen0 - _previousGen0Count.Value);
            }

            if (_previousGen1Count != null)
            {
                _statsd.Increment(MetricsNames.Gen1CollectionsCount, gen1 - _previousGen1Count.Value);
            }

            if (_previousGen2Count != null)
            {
                _statsd.Increment(MetricsNames.Gen2CollectionsCount, gen2 - _previousGen2Count.Value);
            }

            _previousGen0Count = gen0;
            _previousGen1Count = gen1;
            _previousGen2Count = gen2;
        }
        internal void PushEvents()
        {
            try
            {
                _listener?.Refresh();

                if (_enableProcessMetrics)
                {
                    ProcessHelpers.GetCurrentProcessRuntimeMetrics(out var newUserCpu, out var newSystemCpu, out var threadCount, out var memoryUsage);

                    var userCpu   = newUserCpu - _previousUserCpu;
                    var systemCpu = newSystemCpu - _previousSystemCpu;

                    _previousUserCpu   = newUserCpu;
                    _previousSystemCpu = newSystemCpu;

                    // Note: the behavior of Environment.ProcessorCount has changed a lot accross version: https://github.com/dotnet/runtime/issues/622
                    // What we want is the number of cores attributed to the container, which is the behavior in 3.1.2+ (and, I believe, in 2.x)
                    var maximumCpu = Environment.ProcessorCount * _delay.TotalMilliseconds;
                    var totalCpu   = userCpu + systemCpu;

                    _statsd.Gauge(MetricsNames.ThreadsCount, threadCount);

                    _statsd.Gauge(MetricsNames.CommittedMemory, memoryUsage);

                    // Get CPU time in milliseconds per second
                    _statsd.Gauge(MetricsNames.CpuUserTime, userCpu.TotalMilliseconds / _delay.TotalSeconds);
                    _statsd.Gauge(MetricsNames.CpuSystemTime, systemCpu.TotalMilliseconds / _delay.TotalSeconds);

                    _statsd.Gauge(MetricsNames.CpuPercentage, Math.Round(totalCpu.TotalMilliseconds * 100 / maximumCpu, 1, MidpointRounding.AwayFromZero));
                }

                if (!_exceptionCounts.IsEmpty)
                {
                    foreach (var element in _exceptionCounts)
                    {
                        _statsd.Increment(MetricsNames.ExceptionsCount, element.Value, tags: new[] { $"exception_type:{element.Key}" });
                    }

                    // There's a race condition where we could clear items that haven't been pushed
                    // Having an exact exception count is probably not worth the overhead required to fix it
                    _exceptionCounts.Clear();
                }
            }
            catch (Exception ex)
            {
                Log.Warning(ex, "Error while updating runtime metrics");
            }
        }
Beispiel #4
0
        public void WriteTrace(Span[] trace)
        {
            var success = _tracesBuffer.Push(trace);

            if (!success)
            {
                Log.Debug("Trace buffer is full. Dropping a trace from the buffer.");
            }

            if (_statsd != null)
            {
                _statsd.Increment(TracerMetricNames.Queue.EnqueuedTraces);
                _statsd.Increment(TracerMetricNames.Queue.EnqueuedSpans, trace.Length);

                if (!success)
                {
                    _statsd.Increment(TracerMetricNames.Queue.DroppedTraces);
                    _statsd.Increment(TracerMetricNames.Queue.DroppedSpans, trace.Length);
                }
            }
        }
Beispiel #5
0
        protected override void OnEventWritten(EventWrittenEventArgs eventData)
        {
            if (_statsd == null)
            {
                // I know it sounds crazy at first, but because OnEventSourceCreated is called from the base constructor,
                // and EnableEvents is called from OnEventSourceCreated, it's entirely possible that OnEventWritten
                // gets called before the child constructor is called.
                // In that case, just bail out.
                return;
            }

            try
            {
                if (eventData.EventName == "EventCounters")
                {
                    ExtractCounters(eventData.Payload);
                }
                else if (eventData.EventId == EventGcSuspendBegin)
                {
                    _gcStart = eventData.TimeStamp;
                }
                else if (eventData.EventId == EventGcRestartEnd)
                {
                    var start = _gcStart;

                    if (start != null)
                    {
                        _statsd.Timer(MetricsNames.GcPauseTime, (eventData.TimeStamp - start.Value).TotalMilliseconds);
                        Log.Debug("Sent the following metrics: {metrics}", MetricsNames.GcPauseTime);
                    }
                }
                else
                {
                    if (eventData.EventId == EventGcHeapStats)
                    {
                        var stats = HeapStats.FromPayload(eventData.Payload);

                        _statsd.Gauge(MetricsNames.Gen0HeapSize, stats.Gen0Size);
                        _statsd.Gauge(MetricsNames.Gen1HeapSize, stats.Gen1Size);
                        _statsd.Gauge(MetricsNames.Gen2HeapSize, stats.Gen2Size);
                        _statsd.Gauge(MetricsNames.LohSize, stats.LohSize);

                        Log.Debug("Sent the following metrics: {metrics}", GcHeapStatsMetrics);
                    }
                    else if (eventData.EventId == EventContentionStop)
                    {
                        var durationInNanoseconds = (double)eventData.Payload[2];

                        _contentionTime.Time(durationInNanoseconds / 1_000_000);
                        Interlocked.Increment(ref _contentionCount);
                    }
                    else if (eventData.EventId == EventGcGlobalHeapHistory)
                    {
                        var heapHistory = HeapHistory.FromPayload(eventData.Payload);

                        if (heapHistory.MemoryLoad != null)
                        {
                            _statsd.Gauge(MetricsNames.GcMemoryLoad, heapHistory.MemoryLoad.Value);
                        }

                        _statsd.Increment(GcCountMetricNames[heapHistory.Generation], 1, tags: heapHistory.Compacting ? CompactingGcTags : NotCompactingGcTags);
                        Log.Debug("Sent the following metrics: {metrics}", GcGlobalHeapMetrics);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Warning <int, string>(ex, "Error while processing event {EventId} {EventName}", eventData.EventId, eventData.EventName);
            }
        }
Beispiel #6
0
        public async Task CreateInfractionAsync(ulong guildId, ulong moderatorId, InfractionType type, ulong subjectId,
                                                string reason, TimeSpan?duration)
        {
            _authorizationService.RequireClaims(_createInfractionClaimsByType[type]);

            if (reason is null)
            {
                throw new ArgumentNullException(nameof(reason));
            }

            if (reason.Length >= MaxReasonLength)
            {
                throw new ArgumentException($"Reason must be less than {MaxReasonLength} characters in length",
                                            nameof(reason));
            }

            if (((type == InfractionType.Notice) || (type == InfractionType.Warning)) &&
                string.IsNullOrWhiteSpace(reason))
            {
                throw new InvalidOperationException($"{type.ToString()} infractions require a reason to be given");
            }

            var guild = await _discordClient.GetGuildAsync(guildId);

            var subject = await _userService.TryGetGuildUserAsync(guild, subjectId, default);

            await RequireSubjectRankLowerThanModeratorRankAsync(guild, moderatorId, subject);

            using (var transaction = await _infractionRepository.BeginCreateTransactionAsync())
            {
                if ((type == InfractionType.Mute) || (type == InfractionType.Ban))
                {
                    if (await _infractionRepository.AnyAsync(new InfractionSearchCriteria()
                    {
                        GuildId = guildId,
                        Types = new[] { type },
                        SubjectId = subjectId,
                        IsRescinded = false,
                        IsDeleted = false
                    }))
                    {
                        throw new InvalidOperationException(
                                  $"Discord user {subjectId} already has an active {type} infraction");
                    }
                }

                await _infractionRepository.CreateAsync(
                    new InfractionCreationData()
                {
                    GuildId     = guildId,
                    Type        = type,
                    SubjectId   = subjectId,
                    Reason      = reason,
                    Duration    = duration,
                    CreatedById = moderatorId
                });

                transaction.Commit();

                try
                {
                    _dogStatsd.Increment("infractions", tags: new[] { $"infraction_type:{type}", $"guild:{guild.Name}" });
                }
                catch (Exception)
                {
                    // The world mourned, but nothing of tremendous value was lost.
                }
            }

            // TODO: Implement ModerationSyncBehavior to listen for mutes and bans that happen directly in Discord, instead of through bot commands,
            // and to read the Discord Audit Log to check for mutes and bans that were missed during downtime, and add all such actions to
            // the Infractions and ModerationActions repositories.
            // Note that we'll need to upgrade to the latest Discord.NET version to get access to the audit log.

            // Assuming that our Infractions repository is always correct, regarding the state of the Discord API.
            switch (type)
            {
            case InfractionType.Mute when subject is not null:
                await subject.AddRoleAsync(
                    await GetDesignatedMuteRoleAsync(guild));

                break;

            case InfractionType.Ban:
                await guild.AddBanAsync(subjectId, reason : reason);

                break;
            }
        }
 public void Increment(string statName, int value = 1, double sampleRate = 1, string[] tags = null)
 {
     _dogStatsd.Increment(statName, value, sampleRate, tags);
 }
Beispiel #8
0
 public static void Increment(this IDogStatsd stats, string statsName, int value = 1, double sampleRate = 1, List <string> tags = null)
 {
     stats?.Increment(statsName, value, sampleRate, tags?.ToArray());
 }
        private void FirstChanceException(object sender, FirstChanceExceptionEventArgs e)
        {
            var name = e.Exception.GetType().Name;

            _statsd.Increment("runtime.dotnet.exceptions.count", 1, tags: new[] { $"exception_type:{name}" });
        }