<commit_before>﻿using System;
using System.Globalization;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using NLog.Fluent;

namespace Foundatio.Metrics {
    public class StatsDMetricsClient : IMetricsClient {
        private readonly object _lock = new object();
        private Socket _socket;
        private readonly IPEndPoint _endPoint;
        private readonly string _prefix;

        public StatsDMetricsClient(string serverName = "127.0.0.1", int port = 12000, string prefix = "stats") {
            _endPoint = new IPEndPoint(IPAddress.Parse(serverName), port);

            if (!String.IsNullOrEmpty(prefix))
                _prefix = prefix.EndsWith(".") ? prefix : String.Concat(prefix, ".");
        }

        public Task CounterAsync(string statName, int value = 1) {
            Send(BuildMetric("c", statName, value.ToString(CultureInfo.InvariantCulture)));
            return Task.FromResult(0);
        }

        public Task GaugeAsync(string statName, double value) {
            Send(BuildMetric("g", statName, value.ToString(CultureInfo.InvariantCulture)));
            return Task.FromResult(0);
        }

        public Task TimerAsync(string statName, long milliseconds) {
            Send(BuildMetric("ms", statName, milliseconds.ToString(CultureInfo.InvariantCulture)));
            return Task.FromResult(0);
        }

        private string BuildMetric(string type, string statName, string value) {
            return String.Concat(_prefix, statName, ":", value, "|", type);
        }

        private void Send(string metric) {
            if (String.IsNullOrEmpty(metric))
                return;

            try {
                byte[] data = Encoding.ASCII.GetBytes(metric);

                EnsureSocket();
                if (_socket != null)
                    _socket.SendTo(data, _endPoint);
            } catch (Exception ex) {
                Log.Error().Exception(ex).Message("An error occurred while sending the metrics: {0}", ex.Message).Write();
                ResetUdpClient();
            }
        }

        private void EnsureSocket() {
            if (_socket != null)
                return;

            lock (_lock) {
                if (_socket == null)
                    _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            }
        }

        private void ResetUdpClient() {
            if (_socket == null)
                return;

            lock (_lock) {
                try {
                    _socket.Close();
                } catch (Exception ex) {
                    Log.Error().Exception(ex).Message("An error occurred while calling Close() on the socket.").Write();
                } finally {
                    _socket = null;
                }
            }
        }

        public void Dispose() {
            ResetUdpClient();
        }<commit_msg>Fixed a null reference exception with the statsd client.<commit_after>﻿using System;
using System.Globalization;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using NLog.Fluent;

namespace Foundatio.Metrics {
    public class StatsDMetricsClient : IMetricsClient {
        private readonly object _lock = new object();
        private Socket _socket;
        private readonly IPEndPoint _endPoint;
        private readonly string _prefix;

        public StatsDMetricsClient(string serverName = "127.0.0.1", int port = 12000, string prefix = "stats") {
            _endPoint = new IPEndPoint(IPAddress.Parse(serverName), port);

            if (!String.IsNullOrEmpty(prefix))
                _prefix = prefix.EndsWith(".") ? prefix : String.Concat(prefix, ".");
        }

        public Task CounterAsync(string statName, int value = 1) {
            Send(BuildMetric("c", statName, value.ToString(CultureInfo.InvariantCulture)));
            return Task.FromResult(0);
        }

        public Task GaugeAsync(string statName, double value) {
            Send(BuildMetric("g", statName, value.ToString(CultureInfo.InvariantCulture)));
            return Task.FromResult(0);
        }

        public Task TimerAsync(string statName, long milliseconds) {
            Send(BuildMetric("ms", statName, milliseconds.ToString(CultureInfo.InvariantCulture)));
            return Task.FromResult(0);
        }

        private string BuildMetric(string type, string statName, string value) {
            return String.Concat(_prefix, statName, ":", value, "|", type);
        }

        private void Send(string metric) {
            if (String.IsNullOrEmpty(metric))
                return;

            try {
                byte[] data = Encoding.ASCII.GetBytes(metric);

                EnsureSocket();
                if (_socket != null)
                    _socket.SendTo(data, _endPoint);
            } catch (Exception ex) {
                Log.Error().Exception(ex).Message("An error occurred while sending the metrics: {0}", ex.Message).Write();
                ResetUdpClient();
            }
        }

        private void EnsureSocket() {
            if (_socket != null)
                return;

            lock (_lock) {
                if (_socket == null)
                    _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            }
        }

        private void ResetUdpClient() {
            if (_socket == null)
                return;

            lock (_lock) {
                if (_socket == null)
                    return;

                try {
                    _socket.Close();
                } catch (Exception ex) {
                    Log.Error().Exception(ex).Message("An error occurred while calling Close() on the socket.").Write();
                } finally {
                    _socket = null;
                }
            }
        }

        public void Dispose() {
            ResetUdpClient();
        }
{'fraction_non_alphanumeric': 0.10216044213699547, 'fraction_numerical': 0.005359236308825992, 'mean_word_length': 1.803755868544601, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5512305', 'n_tokens_mistral': 1551, 'n_tokens_neox': 1472, 'n_words': 374}