it = stream.iterator();
66 | while (it.hasNext()) {
67 | try {
68 | messageListener.onMessage(new String(it.next().message()));
69 | } catch (RuntimeException e) {
70 | logger.error("consumer kafka metrics message error!", e);
71 | }
72 | }
73 | }
74 | });
75 | }
76 |
77 | }
78 |
79 | public void desotry() {
80 | try {
81 | if (consumer != null) {
82 | consumer.shutdown();
83 | }
84 | } finally {
85 | if (executor != null) {
86 | executor.shutdown();
87 | }
88 | }
89 | }
90 |
91 | public String getZookeeper() {
92 | return zookeeper;
93 | }
94 |
95 | public void setZookeeper(String zookeeper) {
96 | this.zookeeper = zookeeper;
97 | }
98 |
99 | public String getGroup() {
100 | return group;
101 | }
102 |
103 | public void setGroup(String group) {
104 | this.group = group;
105 | }
106 |
107 | public String getTopic() {
108 | return topic;
109 | }
110 |
111 | public void setTopic(String topic) {
112 | this.topic = topic;
113 | }
114 |
115 | public int getThreadNumber() {
116 | return threadNumber;
117 | }
118 |
119 | public void setThreadNumber(int threadNumber) {
120 | this.threadNumber = threadNumber;
121 | }
122 |
123 | public int getZookeeperSessionTimeoutMs() {
124 | return zookeeperSessionTimeoutMs;
125 | }
126 |
127 | public void setZookeeperSessionTimeoutMs(int zookeeperSessionTimeoutMs) {
128 | this.zookeeperSessionTimeoutMs = zookeeperSessionTimeoutMs;
129 | }
130 |
131 | public int getZookeeperSyncTimeMs() {
132 | return zookeeperSyncTimeMs;
133 | }
134 |
135 | public void setZookeeperSyncTimeMs(int zookeeperSyncTimeMs) {
136 | this.zookeeperSyncTimeMs = zookeeperSyncTimeMs;
137 | }
138 |
139 | public int getAutoCommitIntervalMs() {
140 | return autoCommitIntervalMs;
141 | }
142 |
143 | public void setAutoCommitIntervalMs(int autoCommitIntervalMs) {
144 | this.autoCommitIntervalMs = autoCommitIntervalMs;
145 | }
146 |
147 | public MessageListener getMessageListener() {
148 | return messageListener;
149 | }
150 |
151 | public void setMessageListener(MessageListener messageListener) {
152 | this.messageListener = messageListener;
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/main/java/io/github/hengyunabc/metrics/ThreadFactoryBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 The Guava Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package io.github.hengyunabc.metrics;
18 |
19 | import java.lang.Thread.UncaughtExceptionHandler;
20 | import java.util.concurrent.Executors;
21 | import java.util.concurrent.ThreadFactory;
22 | import java.util.concurrent.atomic.AtomicLong;
23 |
24 | /**
25 | * From google guava.
26 | * A ThreadFactory builder, providing any combination of these features:
27 | *
28 | * - whether threads should be marked as {@linkplain Thread#setDaemon daemon}
29 | * threads
30 | *
- a {@linkplain ThreadFactoryBuilder#setNameFormat naming format}
31 | *
- a {@linkplain Thread#setPriority thread priority}
32 | *
- an {@linkplain Thread#setUncaughtExceptionHandler uncaught exception
33 | * handler}
34 | *
- a {@linkplain ThreadFactory#newThread backing thread factory}
35 | *
36 | *
37 | * If no backing thread factory is provided, a default backing thread factory is
38 | * used as if by calling {@code setThreadFactory(}
39 | * {@link Executors#defaultThreadFactory()}{@code )}.
40 | *
41 | * @author Kurt Alfred Kluever
42 | * @since 4.0
43 | */
44 | public final class ThreadFactoryBuilder {
45 | private String nameFormat = null;
46 | private Boolean daemon = null;
47 | private Integer priority = null;
48 | private UncaughtExceptionHandler uncaughtExceptionHandler = null;
49 | private ThreadFactory backingThreadFactory = null;
50 |
51 | /**
52 | * Creates a new {@link ThreadFactory} builder.
53 | */
54 | public ThreadFactoryBuilder() {
55 | }
56 |
57 | /**
58 | * Sets the naming format to use when naming threads ({@link Thread#setName}
59 | * ) which are created with this ThreadFactory.
60 | *
61 | * @param nameFormat
62 | * a {@link String#format(String, Object...)}-compatible format
63 | * String, to which a unique integer (0, 1, etc.) will be
64 | * supplied as the single parameter. This integer will be unique
65 | * to the built instance of the ThreadFactory and will be
66 | * assigned sequentially. For example, {@code "rpc-pool-%d"} will
67 | * generate thread names like {@code "rpc-pool-0"},
68 | * {@code "rpc-pool-1"}, {@code "rpc-pool-2"}, etc.
69 | * @return this for the builder pattern
70 | */
71 | public ThreadFactoryBuilder setNameFormat(String nameFormat) {
72 | String.format(nameFormat, 0); // fail fast if the format is bad or null
73 | this.nameFormat = nameFormat;
74 | return this;
75 | }
76 |
77 | /**
78 | * Sets daemon or not for new threads created with this ThreadFactory.
79 | *
80 | * @param daemon
81 | * whether or not new Threads created with this ThreadFactory
82 | * will be daemon threads
83 | * @return this for the builder pattern
84 | */
85 | public ThreadFactoryBuilder setDaemon(boolean daemon) {
86 | this.daemon = daemon;
87 | return this;
88 | }
89 |
90 | /**
91 | * Sets the priority for new threads created with this ThreadFactory.
92 | *
93 | * @param priority
94 | * the priority for new Threads created with this ThreadFactory
95 | * @return this for the builder pattern
96 | */
97 | public ThreadFactoryBuilder setPriority(int priority) {
98 | // Thread#setPriority() already checks for validity. These error
99 | // messages
100 | // are nicer though and will fail-fast.
101 | checkArgument(priority >= Thread.MIN_PRIORITY, "Thread priority (%s) must be >= %s", priority,
102 | Thread.MIN_PRIORITY);
103 | checkArgument(priority <= Thread.MAX_PRIORITY, "Thread priority (%s) must be <= %s", priority,
104 | Thread.MAX_PRIORITY);
105 | this.priority = priority;
106 | return this;
107 | }
108 |
109 | /**
110 | * Sets the {@link UncaughtExceptionHandler} for new threads created with
111 | * this ThreadFactory.
112 | *
113 | * @param uncaughtExceptionHandler
114 | * the uncaught exception handler for new Threads created with
115 | * this ThreadFactory
116 | * @return this for the builder pattern
117 | */
118 | public ThreadFactoryBuilder setUncaughtExceptionHandler(UncaughtExceptionHandler uncaughtExceptionHandler) {
119 | this.uncaughtExceptionHandler = checkNotNull(uncaughtExceptionHandler);
120 | return this;
121 | }
122 |
123 | /**
124 | * Sets the backing {@link ThreadFactory} for new threads created with this
125 | * ThreadFactory. Threads will be created by invoking #newThread(Runnable)
126 | * on this backing {@link ThreadFactory}.
127 | *
128 | * @param backingThreadFactory
129 | * the backing {@link ThreadFactory} which will be delegated to
130 | * during thread creation.
131 | * @return this for the builder pattern
132 | *
133 | * @see MoreExecutors
134 | */
135 | public ThreadFactoryBuilder setThreadFactory(ThreadFactory backingThreadFactory) {
136 | this.backingThreadFactory = checkNotNull(backingThreadFactory);
137 | return this;
138 | }
139 |
140 | /**
141 | * Returns a new thread factory using the options supplied during the
142 | * building process. After building, it is still possible to change the
143 | * options used to build the ThreadFactory and/or build again. State is not
144 | * shared amongst built instances.
145 | *
146 | * @return the fully constructed {@link ThreadFactory}
147 | */
148 | public ThreadFactory build() {
149 | return build(this);
150 | }
151 |
152 | private static ThreadFactory build(ThreadFactoryBuilder builder) {
153 | final String nameFormat = builder.nameFormat;
154 | final Boolean daemon = builder.daemon;
155 | final Integer priority = builder.priority;
156 | final UncaughtExceptionHandler uncaughtExceptionHandler = builder.uncaughtExceptionHandler;
157 | final ThreadFactory backingThreadFactory = (builder.backingThreadFactory != null) ? builder.backingThreadFactory
158 | : Executors.defaultThreadFactory();
159 | final AtomicLong count = (nameFormat != null) ? new AtomicLong(0) : null;
160 | return new ThreadFactory() {
161 | @Override
162 | public Thread newThread(Runnable runnable) {
163 | Thread thread = backingThreadFactory.newThread(runnable);
164 | if (nameFormat != null) {
165 | thread.setName(String.format(nameFormat, count.getAndIncrement()));
166 | }
167 | if (daemon != null) {
168 | thread.setDaemon(daemon);
169 | }
170 | if (priority != null) {
171 | thread.setPriority(priority);
172 | }
173 | if (uncaughtExceptionHandler != null) {
174 | thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
175 | }
176 | return thread;
177 | }
178 | };
179 | }
180 |
181 | /**
182 | * Substitutes each {@code %s} in {@code template} with an argument. These
183 | * are matched by position: the first {@code %s} gets {@code args[0]}, etc.
184 | * If there are more arguments than placeholders, the unmatched arguments
185 | * will be appended to the end of the formatted message in square braces.
186 | *
187 | * @param template
188 | * a non-null string containing 0 or more {@code %s}
189 | * placeholders.
190 | * @param args
191 | * the arguments to be substituted into the message template.
192 | * Arguments are converted to strings using
193 | * {@link String#valueOf(Object)}. Arguments can be null.
194 | */
195 | // Note that this is somewhat-improperly used from Verify.java as well.
196 | static String format(String template, Object... args) {
197 | template = String.valueOf(template); // null -> "null"
198 |
199 | // start substituting the arguments into the '%s' placeholders
200 | StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
201 | int templateStart = 0;
202 | int i = 0;
203 | while (i < args.length) {
204 | int placeholderStart = template.indexOf("%s", templateStart);
205 | if (placeholderStart == -1) {
206 | break;
207 | }
208 | builder.append(template.substring(templateStart, placeholderStart));
209 | builder.append(args[i++]);
210 | templateStart = placeholderStart + 2;
211 | }
212 | builder.append(template.substring(templateStart));
213 |
214 | // if we run out of placeholders, append the extra args in square braces
215 | if (i < args.length) {
216 | builder.append(" [");
217 | builder.append(args[i++]);
218 | while (i < args.length) {
219 | builder.append(", ");
220 | builder.append(args[i++]);
221 | }
222 | builder.append(']');
223 | }
224 |
225 | return builder.toString();
226 | }
227 |
228 | /**
229 | * Ensures the truth of an expression involving one or more parameters to
230 | * the calling method.
231 | *
232 | * @param expression
233 | * a boolean expression
234 | * @param errorMessageTemplate
235 | * a template for the exception message should the check fail.
236 | * The message is formed by replacing each {@code %s} placeholder
237 | * in the template with an argument. These are matched by
238 | * position - the first {@code %s} gets
239 | * {@code errorMessageArgs[0]}, etc. Unmatched arguments will be
240 | * appended to the formatted message in square braces. Unmatched
241 | * placeholders will be left as-is.
242 | * @param errorMessageArgs
243 | * the arguments to be substituted into the message template.
244 | * Arguments are converted to strings using
245 | * {@link String#valueOf(Object)}.
246 | * @throws IllegalArgumentException
247 | * if {@code expression} is false
248 | * @throws NullPointerException
249 | * if the check fails and either {@code errorMessageTemplate} or
250 | * {@code errorMessageArgs} is null (don't let this happen)
251 | */
252 | private void checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
253 | if (!expression) {
254 | throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs));
255 | }
256 |
257 | }
258 |
259 | /**
260 | * Ensures that an object reference passed as a parameter to the calling
261 | * method is not null.
262 | *
263 | * @param reference
264 | * an object reference
265 | * @return the non-null reference that was validated
266 | * @throws NullPointerException
267 | * if {@code reference} is null
268 | */
269 | public static T checkNotNull(T reference) {
270 | if (reference == null) {
271 | throw new NullPointerException();
272 | }
273 | return reference;
274 | }
275 |
276 | }
277 |
--------------------------------------------------------------------------------
/src/test/java/io/github/hengyunabc/metrics/test/AnnotationObject.java:
--------------------------------------------------------------------------------
1 | package io.github.hengyunabc.metrics.test;
2 |
3 | import java.util.Random;
4 | import java.util.concurrent.TimeUnit;
5 |
6 | import com.codahale.metrics.annotation.Timed;
7 | import com.ryantenney.metrics.annotation.Counted;
8 |
9 | public class AnnotationObject {
10 |
11 | Random random = new Random();
12 |
13 | /**
14 | * stat call times and time.
15 | */
16 | @Timed
17 | public void call() {
18 | try {
19 | TimeUnit.MILLISECONDS.sleep(random.nextInt(3000));
20 | } catch (InterruptedException e) {
21 | e.printStackTrace();
22 | }
23 | }
24 |
25 | /**
26 | * stat user login times.
27 | */
28 | @Counted
29 | public void userLogin(){
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/io/github/hengyunabc/metrics/test/KafkaReporterSample.java:
--------------------------------------------------------------------------------
1 | package io.github.hengyunabc.metrics.test;
2 |
3 | import java.io.IOException;
4 | import java.util.Properties;
5 | import java.util.Timer;
6 | import java.util.TimerTask;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | import com.codahale.metrics.ConsoleReporter;
10 | import com.codahale.metrics.Histogram;
11 | import com.codahale.metrics.MetricRegistry;
12 | import com.codahale.metrics.Timer.Context;
13 | import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
14 | import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
15 |
16 | import io.github.hengyunabc.metrics.KafkaReporter;
17 | import kafka.producer.ProducerConfig;
18 |
19 | public class KafkaReporterSample {
20 | static final MetricRegistry metrics = new MetricRegistry();
21 | static public Timer timer = new Timer();
22 |
23 | public static void main(String args[]) throws IOException,
24 | InterruptedException {
25 | ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics)
26 | .convertRatesTo(TimeUnit.SECONDS)
27 | .convertDurationsTo(TimeUnit.MILLISECONDS).build();
28 | metrics.register("jvm.mem", new MemoryUsageGaugeSet());
29 | metrics.register("jvm.gc", new GarbageCollectorMetricSet());
30 |
31 | final Histogram responseSizes = metrics.histogram("response-sizes");
32 | final com.codahale.metrics.Timer metricsTimer = metrics
33 | .timer("test-timer");
34 |
35 | timer.schedule(new TimerTask() {
36 | int i = 100;
37 |
38 | @Override
39 | public void run() {
40 | Context context = metricsTimer.time();
41 | try {
42 | TimeUnit.MILLISECONDS.sleep(500);
43 | } catch (InterruptedException e) {
44 | // TODO Auto-generated catch block
45 | e.printStackTrace();
46 | }
47 | responseSizes.update(i++);
48 | context.stop();
49 | }
50 |
51 | }, 1000, 1000);
52 |
53 | reporter.start(5, TimeUnit.SECONDS);
54 |
55 | String hostName = "localhost";
56 | String topic = "test-kafka-reporter";
57 | Properties props = new Properties();
58 | props.put("metadata.broker.list", "127.0.0.1:9092");
59 | props.put("serializer.class", "kafka.serializer.StringEncoder");
60 | props.put("partitioner.class", "kafka.producer.DefaultPartitioner");
61 | props.put("request.required.acks", "1");
62 |
63 | String prefix = "test.";
64 | ProducerConfig config = new ProducerConfig(props);
65 | KafkaReporter kafkaReporter = KafkaReporter.forRegistry(metrics)
66 | .config(config).topic(topic).hostName(hostName).prefix(prefix).build();
67 |
68 | kafkaReporter.start(1, TimeUnit.SECONDS);
69 |
70 | TimeUnit.SECONDS.sleep(500);
71 | }
72 | }
--------------------------------------------------------------------------------
/src/test/java/io/github/hengyunabc/metrics/test/MetricsKafkaConsumerSample.java:
--------------------------------------------------------------------------------
1 | package io.github.hengyunabc.metrics.test;
2 |
3 | import java.io.IOException;
4 |
5 | import io.github.hengyunabc.metrics.MessageListener;
6 | import io.github.hengyunabc.metrics.MetricsKafkaConsumer;
7 |
8 | public class MetricsKafkaConsumerSample {
9 |
10 | String zookeeper;
11 | String topic;
12 | String group;
13 |
14 | MetricsKafkaConsumer consumer;
15 |
16 | public static void main(String[] args) throws IOException {
17 |
18 | String zookeeper = "localhost:2181";
19 | String topic = "test-kafka-reporter";
20 | String group = "consumer-test";
21 |
22 | MetricsKafkaConsumer consumer = new MetricsKafkaConsumer();
23 |
24 | consumer = new MetricsKafkaConsumer();
25 | consumer.setZookeeper(zookeeper);
26 | consumer.setTopic(topic);
27 | consumer.setGroup(group);
28 | consumer.setMessageListener(new MessageListener() {
29 |
30 | @Override
31 | public void onMessage(String message) {
32 | System.err.println(message);
33 | }
34 | });
35 | consumer.init();
36 |
37 | System.in.read();
38 |
39 | consumer.desotry();
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/java/io/github/hengyunabc/metrics/test/SpringTest.java:
--------------------------------------------------------------------------------
1 | package io.github.hengyunabc.metrics.test;
2 |
3 | import io.github.hengyunabc.metrics.KafkaReporter;
4 |
5 | import java.util.Properties;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | import kafka.producer.ProducerConfig;
9 |
10 | import org.junit.Before;
11 | import org.junit.Test;
12 | import org.junit.runner.RunWith;
13 | import org.springframework.aop.framework.AopContext;
14 | import org.springframework.beans.factory.annotation.Autowired;
15 | import org.springframework.test.context.ContextConfiguration;
16 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
17 |
18 | import com.codahale.metrics.MetricRegistry;
19 |
20 | @RunWith(SpringJUnit4ClassRunner.class)
21 | @ContextConfiguration("classpath:spring-test.xml")
22 | public class SpringTest {
23 |
24 | @Autowired
25 | AnnotationObject annotationObject;
26 |
27 | @Autowired
28 | MetricRegistry metrics;
29 |
30 | @Before
31 | public void before(){
32 | startKafkaReporter();
33 | }
34 |
35 | public void startKafkaReporter(){
36 | String hostName = "192.168.66.30";
37 | String topic = "test-kafka-reporter";
38 | Properties props = new Properties();
39 | props.put("metadata.broker.list", "192.168.90.147:9091");
40 | props.put("serializer.class", "kafka.serializer.StringEncoder");
41 | props.put("partitioner.class", "kafka.producer.DefaultPartitioner");
42 | props.put("request.required.acks", "1");
43 |
44 | String prefix = "test.";
45 | ProducerConfig config = new ProducerConfig(props);
46 | KafkaReporter kafkaReporter = KafkaReporter.forRegistry(metrics)
47 | .config(config).topic(topic).hostName(hostName).prefix(prefix).build();
48 |
49 | kafkaReporter.start(3, TimeUnit.SECONDS);
50 | }
51 |
52 | @Test
53 | public void test() throws InterruptedException{
54 | Thread t = new Thread(new Runnable() {
55 | @Override
56 | public void run() {
57 | while (true) {
58 | annotationObject.call();
59 | annotationObject.userLogin();
60 | }
61 | }
62 | });
63 | t.start();
64 |
65 | TimeUnit.SECONDS.sleep(500);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Root logger option
2 | log4j.rootLogger=INFO, stdout
3 |
4 | # Direct log messages to a log file
5 | log4j.appender.file=org.apache.log4j.RollingFileAppender
6 | log4j.appender.file.File=C:\\logging.log
7 | log4j.appender.file.MaxFileSize=10MB
8 | log4j.appender.file.MaxBackupIndex=10
9 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
10 | log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
11 |
12 | # Direct log messages to stdout
13 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
14 | log4j.appender.stdout.Target=System.out
15 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
16 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
--------------------------------------------------------------------------------
/src/test/resources/spring-test.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
21 |
23 |
24 |
26 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------