转载请注明出处:https://blog.csdn.net/l1028386804/article/details/89376379

Storm Metric类似于Hadoop的Counter,用于手机应用程序中的特定指标,输出到输出到外部,在Storm中是存储到各个机器logs目录下的metric.log文件。有时我们想保存一些计算的中间变量,当达到一定状态时,统一在一个位置输出,或者统计整合应用的一些指标,Metric是个很好的选择。如果在Bolt类中存储变量,只能统计该Bolt的一些信息,无法取到其他Bolt的状态信息。用户可以直接使用LoggingMetricsConsumer类,将统计指标写入MetricConsumer接口,这些类可以通过函数registerMetricsConsumer注册,也可以在配置文件storm.yaml中注册。我们定义一个MonitorKafkaLogConsumer的自定义类

package com.lyz.hadoop.storm.metric;

import java.util.Collection;
import java.util.Map;

import org.apache.storm.metric.api.IMetricsConsumer;
import org.apache.storm.task.IErrorReporter;
import org.apache.storm.task.TopologyContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MinitorKafkaLogConsumer implements IMetricsConsumer {
	private final Logger logger = LoggerFactory.getLogger(MinitorKafkaLogConsumer.class);
	@Override
	public void prepare(Map stormConf, Object registrationArgument, TopologyContext context,
			IErrorReporter errorReporter) {

	}
	@Override
	public void handleDataPoints(TaskInfo taskInfo, Collection<DataPoint> dataPoints) {
		for(DataPoint p : dataPoints) {
			logger.info((p.name + ":" + p.value));
		}
	}
	@Override
	public void cleanup() {

	}
}

然后把MonitorKafkaLogConsumer注册到 registerMetricsConsumer中。

Config conf = new Config();
//输出统计指标值到日志文件中
conf.registerMetricsConsumer(MinitorKafkaLogConsumer.class, 5);
StormSubmitter.submitTopology(args[0], conf, builder.createTopology());

最后,在具体业务的Bolt中加入需要统计的值,比如统计用户的访问次数。

package com.lyz.hadoop.storm.metric;

import java.util.Map;

import org.apache.storm.metric.api.CountMetric;
import org.apache.storm.metric.api.MultiCountMetric;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.BasicOutputCollector;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseBasicBolt;
import org.apache.storm.tuple.Tuple;

public class MonitorUserActionBolt extends BaseBasicBolt {

	private static final long serialVersionUID = -7650845624664389481L;
	
	private transient MultiCountMetric userProfileStatMetric;
	//浏览行为
	private static final String USER_ACTION_BROWSE = "Bro";
	
	@Override
	public void prepare(Map stormConf, TopologyContext context) {
		super.prepare(stormConf, context);
		this.userProfileStatMetric = new MultiCountMetric();
		//每10秒统计一些浏览行为的次数
		context.registerMetric("useraction_count", userProfileStatMetric, 10);
	}
	
	public void updateUserActionMetric(UserActionTuple userAction) {
		if(USER_ACTION_BROWSE.equalIgnoreCase(userAction.getUserType())) {
			CountMetric broCount = userProfileStatMetric.scope(USER_ACTION_BROWSE);
			broCount.incr();
		}
	}
	
	@Override
	public void execute(Tuple input, BasicOutputCollector collector) {
		Object msg = input.getValueByField("trackInfos");
		//用户行为的自定义类
		UserActionTuple userAction = (UserActionTuple)msg;
		updateUserActionMetric(userAction);
	}
	
	@Override
	public void declareOutputFields(OutputFieldsDeclarer declarer) {

	}
}

这样,通过Metric信息可以将所关心的业务指标数据提取出来,发送到相应的系统中,用于监控和报警。