forked from statsd/statsd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
StatsdClient.java
155 lines (131 loc) · 4.11 KB
/
StatsdClient.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**
* StatsdClient.java
*
* (C) 2011 Meetup, Inc.
* Author: Andrew Gwozdziewycz <[email protected]>, @apgwoz
*
*
*
* Example usage:
*
* StatsdClient client = new StatsdClient("statsd.example.com", 8125);
* // increment by 1
* client.increment("foo.bar.baz");
* // increment by 10
* client.increment("foo.bar.baz", 10);
* // sample rate
* client.increment("foo.bar.baz", 10, .1);
* // increment multiple keys by 1
* client.increment("foo.bar.baz", "foo.bar.boo", "foo.baz.bar");
* // increment multiple keys by 10 -- yeah, it's "backwards"
* client.increment(10, "foo.bar.baz", "foo.bar.boo", "foo.baz.bar");
* // multiple keys with a sample rate
* client.increment(10, .1, "foo.bar.baz", "foo.bar.boo", "foo.baz.bar");
*
* Note: For best results, and greater availability, you'll probably want to
* create a wrapper class which creates a static client and proxies to it.
*
* You know... the "Java way."
*/
import java.util.Random;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import org.apache.log4j.Logger;
public class StatsdClient {
private static Random RNG = new Random();
private static Logger log = Logger.getLogger(StatsdClient.class.getName());
private InetAddress _host;
private int _port;
private DatagramSocket _sock;
public StatsdClient(String host, int port) throws UnknownHostException, SocketException {
this(InetAddress.getByName(host), port);
}
public StatsdClient(InetAddress host, int port) throws SocketException {
_host = host;
_port = port;
_sock = new DatagramSocket();
}
public boolean timing(String key, int value) {
return timing(key, value, 1.0);
}
public boolean timing(String key, int value, double sampleRate) {
return send(sampleRate, String.format("%s:%d|ms", key, value));
}
public boolean decrement(String key) {
return increment(key, -1, 1.0);
}
public boolean decrement(String key, int magnitude) {
return decrement(key, magnitude, 1.0);
}
public boolean decrement(String key, int magnitude, double sampleRate) {
magnitude = magnitude < 0 ? magnitude: -magnitude;
return increment(key, magnitude, sampleRate);
}
public boolean decrement(String... keys) {
return increment(-1, 1.0, keys);
}
public boolean decrement(int magnitude, String... keys) {
magnitude = magnitude < 0 ? magnitude: -magnitude;
return increment(magnitude, 1.0, keys);
}
public boolean decrement(int magnitude, double sampleRate, String... keys) {
magnitude = magnitude < 0 ? magnitude: -magnitude;
return increment(magnitude, sampleRate, keys);
}
public boolean increment(String key) {
return increment(key, 1, 1.0);
}
public boolean increment(String key, int magnitude) {
return increment(key, magnitude, 1.0);
}
public boolean increment(String key, int magnitude, double sampleRate) {
String stat = String.format("%s:%s|c", key, magnitude);
return send(stat, sampleRate);
}
public boolean increment(int magnitude, double sampleRate, String... keys) {
String[] stats = new String[keys.length];
for (int i = 0; i < keys.length; i++) {
stats[i] = String.format("%s:%s|c", keys[i], magnitude);
}
return send(sampleRate, stats);
}
private boolean send(String stat, double sampleRate) {
return send(sampleRate, stat);
}
private boolean send(double sampleRate, String... stats) {
boolean retval = false; // didn't send anything
if (sampleRate < 1.0) {
for (String stat : stats) {
if (RNG.nextDouble() <= sampleRate) {
stat = String.format("%s|@%f", stat, sampleRate);
if (doSend(stat)) {
retval = true;
}
}
}
}
else {
for (String stat : stats) {
if (doSend(stat)) {
retval = true;
}
}
}
return retval;
}
private boolean doSend(String stat) {
try {
byte[] data = stat.getBytes();
_sock.send(new DatagramPacket(data, data.length, _host, _port));
return true;
}
catch (IOException e) {
log.error(String.format("Could not send stat %s to host %s:%d", stat, _host, _port), e);
}
return false;
}
}