1 | using System;
|
2 | using System.Linq;
|
3 | using System.Net.Sockets;
|
4 | using System.Text;
|
5 |
|
6 | namespace Statsd
|
7 | {
|
8 | public class StatsdPipe : IDisposable
|
9 | {
|
10 | private readonly UdpClient udpClient;
|
11 |
|
12 | [ThreadStatic]
|
13 | private static Random random;
|
14 |
|
15 | private static Random Random
|
16 | {
|
17 | get
|
18 | {
|
19 | return random ?? (random = new Random());
|
20 | }
|
21 | }
|
22 |
|
23 | public StatsdPipe(string host, int port)
|
24 | {
|
25 | udpClient = new UdpClient(host, port);
|
26 | }
|
27 |
|
28 | public bool Gauge(string key, int value)
|
29 | {
|
30 | return Gauge(key, value, 1.0);
|
31 | }
|
32 |
|
33 | public bool Gauge(string key, int value, double sampleRate)
|
34 | {
|
35 | return Send(sampleRate, String.Format("{0}:{1:d}|g", key, value));
|
36 | }
|
37 |
|
38 | public bool Timing(string key, int value)
|
39 | {
|
40 | return Timing(key, value, 1.0);
|
41 | }
|
42 |
|
43 | public bool Timing(string key, int value, double sampleRate)
|
44 | {
|
45 | return Send(sampleRate, String.Format("{0}:{1:d}|ms", key, value));
|
46 | }
|
47 |
|
48 | public bool Decrement(string key)
|
49 | {
|
50 | return Increment(key, -1, 1.0);
|
51 | }
|
52 |
|
53 | public bool Decrement(string key, int magnitude)
|
54 | {
|
55 | return Decrement(key, magnitude, 1.0);
|
56 | }
|
57 |
|
58 | public bool Decrement(string key, int magnitude, double sampleRate)
|
59 | {
|
60 | magnitude = magnitude < 0 ? magnitude : -magnitude;
|
61 | return Increment(key, magnitude, sampleRate);
|
62 | }
|
63 |
|
64 | public bool Decrement(params string[] keys)
|
65 | {
|
66 | return Increment(-1, 1.0, keys);
|
67 | }
|
68 |
|
69 | public bool Decrement(int magnitude, params string[] keys)
|
70 | {
|
71 | magnitude = magnitude < 0 ? magnitude : -magnitude;
|
72 | return Increment(magnitude, 1.0, keys);
|
73 | }
|
74 |
|
75 | public bool Decrement(int magnitude, double sampleRate, params string[] keys)
|
76 | {
|
77 | magnitude = magnitude < 0 ? magnitude : -magnitude;
|
78 | return Increment(magnitude, sampleRate, keys);
|
79 | }
|
80 |
|
81 | public bool Increment(string key)
|
82 | {
|
83 | return Increment(key, 1, 1.0);
|
84 | }
|
85 |
|
86 | public bool Increment(string key, int magnitude)
|
87 | {
|
88 | return Increment(key, magnitude, 1.0);
|
89 | }
|
90 |
|
91 | public bool Increment(string key, int magnitude, double sampleRate)
|
92 | {
|
93 | string stat = String.Format("{0}:{1}|c", key, magnitude);
|
94 | return Send(stat, sampleRate);
|
95 | }
|
96 |
|
97 | public bool Increment(int magnitude, double sampleRate, params string[] keys)
|
98 | {
|
99 | return Send(sampleRate, keys.Select(key => String.Format("{0}:{1}|c", key, magnitude)).ToArray());
|
100 | }
|
101 |
|
102 | protected bool Send(String stat, double sampleRate)
|
103 | {
|
104 | return Send(sampleRate, stat);
|
105 | }
|
106 |
|
107 | protected bool Send(double sampleRate, params string[] stats)
|
108 | {
|
109 | var retval = false;
|
110 | if (sampleRate < 1.0)
|
111 | {
|
112 | foreach (var stat in stats)
|
113 | {
|
114 | if (Random.NextDouble() <= sampleRate)
|
115 | {
|
116 | var statFormatted = String.Format("{0}|@{1:f}", stat, sampleRate);
|
117 | if (DoSend(statFormatted))
|
118 | {
|
119 | retval = true;
|
120 | }
|
121 | }
|
122 | }
|
123 | }
|
124 | else
|
125 | {
|
126 | foreach (var stat in stats)
|
127 | {
|
128 | if (DoSend(stat))
|
129 | {
|
130 | retval = true;
|
131 | }
|
132 | }
|
133 | }
|
134 |
|
135 | return retval;
|
136 | }
|
137 |
|
138 | protected bool DoSend(string stat)
|
139 | {
|
140 | var data = Encoding.Default.GetBytes(stat + "\n");
|
141 |
|
142 | udpClient.Send(data, data.Length);
|
143 | return true;
|
144 | }
|
145 |
|
146 | #region IDisposable Members
|
147 |
|
148 | public void Dispose()
|
149 | {
|
150 | try
|
151 | {
|
152 | if (udpClient != null)
|
153 | {
|
154 | udpClient.Close();
|
155 | }
|
156 | }
|
157 | catch
|
158 | {
|
159 | }
|
160 | }
|
161 |
|
162 | #endregion
|
163 | }
|
164 | }
|