目的

实时监听某目录下的日志文件,如有新文件切换到新文件,并同步写入kafka,同时记录日志文件的行位置,以应对进程异常退出,能从上次的文件位置开始读取(考虑到效率,这里是每100条记一次,可调整)
 

源码:

  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileReader;
  7. import java.io.FileWriter;
  8. import java.io.IOException;
  9. import java.io.LineNumberReader;
  10. import java.io.PrintWriter;
  11. import java.io.RandomAccessFile;
  12. import java.net.NoRouteToHostException;
  13. import java.util.ArrayList;
  14. import java.util.Collection;
  15. import java.util.List;
  16. import java.util.Properties;
  17. import java.util.Random;
  18. import java.util.concurrent.Executors;
  19. import java.util.concurrent.ScheduledExecutorService;
  20. import java.util.concurrent.TimeUnit;
  21. import kafka.javaapi.producer.Producer;
  22. import kafka.producer.KeyedMessage;
  23. import kafka.producer.ProducerConfig;
  24. /*
  25. * 自己在源服务器写生产者往kafka插入数据,注意文件"producer.properties放在linux下该jar文件同一目录
  26. * 监听某个目录下的文件数据然后写入kafka
  27. * nohup java -jar portallog_producer.jar portallog /var/apache/logs portallog.position  >/home/sre/portalhandler/handler.log 2>&1 &
  28. *
  29. *
  30. */
  31. public class PortalLogTail_Line {
  32. private Producer<String,String> inner;
  33. java.util.Random ran = new Random();
  34. public PortalLogTail_Line() throws FileNotFoundException, IOException {
  35. Properties properties = new Properties();
  36. //   properties.load(ClassLoader.getSystemResourceAsStream("producer.properties"));
  37. properties.load(new FileInputStream("producer.properties"));
  38. ProducerConfig config = new ProducerConfig(properties);
  39. inner = new Producer<String, String>(config);
  40. }
  41. public void send(String topicName,String message) {
  42. if(topicName == null || message == null){
  43. return;
  44. }
  45. //   KeyedMessage<String, String> km = new KeyedMessage<String, String>(topicName,message);
  46. //随机作为key,hash分散到各个分区
  47. KeyedMessage<String, String> km = new KeyedMessage<String, String>(topicName,String.valueOf(ran.nextInt(9)),message);
  48. //   KeyedMessage<String, String> km = new KeyedMessage<String, String>(topicName,message,message);
  49. inner.send(km);
  50. }
  51. public void send(String topicName,Collection<String> messages) {
  52. if(topicName == null || messages == null){
  53. return;
  54. }
  55. if(messages.isEmpty()){
  56. return;
  57. }
  58. List<KeyedMessage<String, String>> kms = new ArrayList<KeyedMessage<String, String>>();
  59. for(String entry : messages){
  60. KeyedMessage<String, String> km = new KeyedMessage<String, String>(topicName,entry);
  61. kms.add(km);
  62. }
  63. inner.send(kms);
  64. }
  65. public void close(){
  66. inner.close();
  67. }
  68. public String getNewFile(File file)
  69. {
  70. File[] fs=file.listFiles();
  71. long maxtime=0;
  72. String newfilename="";
  73. for (int i=0;i<fs.length;i++)
  74. {
  75. if (fs[i].lastModified()>maxtime && fs[i].getName().contains("access"))
  76. {
  77. maxtime=fs[i].lastModified();
  78. newfilename=fs[i].getAbsolutePath();
  79. }
  80. }
  81. return newfilename;
  82. }
  83. //写入文件名及行号
  84. public void writePosition(String path,int rn,String positionpath)
  85. {
  86. try {
  87. BufferedWriter out = new BufferedWriter(new FileWriter(positionpath));
  88. out.write(path+","+rn);
  89. out.close();
  90. } catch (IOException e) {
  91. }
  92. }
  93. LineNumberReader randomFile=null;
  94. String newfile=null;
  95. String thisfile=null;
  96. String prefile=null;
  97. int ln=0;
  98. int beginln=0;
  99. public void realtimeShowLog(final File file,final String topicname, final String positionpath) throws IOException{
  100. //启动一个线程每1秒钟读取新增的日志信息
  101. new Thread(new Runnable(){
  102. public void run() {
  103. thisfile=getNewFile(file);
  104. prefile=thisfile;
  105. //访问position文件,如果记录了文件路径,及行号,则定位,否则使用最新的文件
  106. try {
  107. BufferedReader br=new BufferedReader(new FileReader(positionpath));
  108. String line=br.readLine();
  109. if (line!=null &&line.contains(","))
  110. {
  111. thisfile=line.split(",")[0];
  112. prefile=thisfile;
  113. beginln=Integer.parseInt(line.split(",")[1]);
  114. }
  115. } catch (FileNotFoundException e2) {
  116. // TODO Auto-generated catch block
  117. e2.printStackTrace();
  118. }
  119. catch (IOException e2) {
  120. // TODO Auto-generated catch block
  121. e2.printStackTrace();
  122. }
  123. //指定文件可读可写
  124. try {
  125. randomFile = new LineNumberReader(new FileReader(thisfile));
  126. } catch (FileNotFoundException e) {
  127. // TODO Auto-generated catch block
  128. e.printStackTrace();
  129. }
  130. while (true)
  131. {
  132. try {
  133. Thread.sleep(100);
  134. } catch (InterruptedException e1) {
  135. // TODO Auto-generated catch block
  136. e1.printStackTrace();
  137. }
  138. try {
  139. //获得变化部分的
  140. //  randomFile.seek(lastTimeFileSize);
  141. String tmp = "";
  142. while( (tmp = randomFile.readLine())!= null) {
  143. int currln=randomFile.getLineNumber();
  144. //beginln默认为0
  145. if (currln>beginln)
  146. send(topicname,new String(tmp.getBytes("utf8")));
  147. ln++;
  148. //每发生一条写一次影响效率,连续发100次后再记录位置
  149. if (ln>100)
  150. {
  151. writePosition(thisfile,currln,positionpath);
  152. ln=0;
  153. }
  154. }
  155. thisfile=getNewFile(file);
  156. if(!thisfile.equals(prefile))
  157. {
  158. randomFile.close();
  159. randomFile = new LineNumberReader(new FileReader(thisfile));
  160. prefile=thisfile;
  161. beginln=0;
  162. }
  163. } catch (IOException e) {
  164. throw new RuntimeException(e);
  165. }
  166. }
  167. }}).start();
  168. }
  169. /**
  170. * @param args
  171. * @throws Exception
  172. */
  173. public static void main(String[] args) throws Exception {
  174. PortalLogTail_Line producer = new PortalLogTail_Line();
  175. if (args.length!=3)
  176. {
  177. System.out.println("usage:topicname pathname positionpath");
  178. System.exit(1);
  179. }
  180. String topicname=args[0];
  181. String pathname=args[1];
  182. String positionpath=args[2];
  183. final File tmpLogFile = new File(pathname);
  184. producer.realtimeShowLog(tmpLogFile,topicname,positionpath);
  185. }
  186. }
 
producer.properties文件放在同级目录下
  1. metadata.broker.list=xxx:10909,xxx:10909
  2. # name of the partitioner class for partitioning events; default partition spreads data randomly
  3. #partitioner.class=
  4. # specifies whether the messages are sent asynchronously (async) or synchronously (sync)
  5. producer.type=sync
  6. #producer.type=async
  7. # specify the compression codec for all data generated: none , gzip, snappy.
  8. # the old config values work as well: 0, 1, 2 for none, gzip, snappy, respectivally
  9. compression.codec=none
  10. #compression.codec=gzip
  11. # message encoder
  12. serializer.class=kafka.serializer.StringEncoder
 

测试

最后执行:

  1. nohup java -jar portallog_producer.jar portallog /var/apache/logs portallog.position  >/home/sre/portalhandler/handler.log 2>&1 &
  2. 转:http://blog.csdn.net/u011750989/article/details/21237251

java实时监听日志写入kafka的更多相关文章

  1. java实时监听日志写入kafka(转)

    原文链接:http://www.sjsjw.com/kf_cloud/article/020376ABA013802.asp 目的 实时监听某目录下的日志文件,如有新文件切换到新文件,并同步写入kaf ...

  2. java实时监听日志写入kafka(多目录)

    目的 实时监听多个目录下的日志文件,如有新文件切换到新文件,并同步写入kafka,同时记录日志文件的行位置,以应对进程异常退出,能从上次的文件位置开始读取(考虑到效率,这里是每100条记一次,可调整) ...

  3. 20180530利用Maxwell组件实时监听Mysql的binlog日志

    转自:https://blog.csdn.net/qq_30921461/article/details/78320750 http://kafka.apache.org/quickstart htt ...

  4. js 实时监听input中值变化

    注意:用到了jquery需要引入jquery.min.js. 需求: 1.每个地方需要分别打分,总分为100; 2.第一个打分总分为40; 3.第二个打分总分为60. 注意:需要判断null.&quo ...

  5. ORACLE清理、截断监听日志文件(listener.log)

    在ORACLE数据库中,如果不对监听日志文件(listener.log)进行截断,那么监听日志文件(listener.log)会变得越来越大,想必不少人听说过关于"LISTENER.LOG日 ...

  6. Java线程监听,意外退出线程后自动重启

    Java线程监听,意外退出线程后自动重启 某日,天朗气清,回公司,未到9点,刷微博,顿觉问题泛滥,惊恐万分! 前一天写了一个微博爬行程序,主要工作原理就是每隔2分钟爬行一次微博,获取某N个关注朋友微博 ...

  7. Android实时监听网络状态

    Android实时监听网络状态(1)   其实手机在网络方面的的监听也比较重要,有时候我们必须实时监控这个程序的实时网络状态,android在网络断开与连接的时候都会发出广播,我们通过接收系统的广播就 ...

  8. Oracle数据库运维:要对监听日志文件(listener.log)进行定期清理,如果不定期清理,会遇到下面一些麻烦

    原文链接: http://www.lookdaima.com/WebForms/WebPages/Blanks/Pm/Docs/DocItemDetail.aspx?EmPreviewTypeV=2& ...

  9. 移动端用js与jquery实时监听输入框值的改动

    背景: 在一次移动端H5开发中,需要监听输入框值的实时变动. onchange事件肯定抛弃,因为只能失去焦点才触发. 而keyPress在Android可以触发,iOS不可以. 又不想用Android ...

随机推荐

  1. css3 animatehue属性

    -webkit-perspective(-moz,-o,perspective下同)表示透视范围大小: -webkit-transform-style很好理解了,表示变换类型,preserve-3d看 ...

  2. IO文件操作

    × 目录 [1]IO文件的操作 [2]Directory类 [3]File类 [4]FileStream类 [5]文本文件的操作 一.IO文件的操作:   .net中对文件操作,经常会用到这样几个类: ...

  3. jsp:jsp包含文件的两种方式

    第一种:include指令 include指令:当JSP转换成Servlet时引入指定文件(指令元素),这是一种静态包含,它运行的时候不会单独编译成.class文件,它生成一个新的整体.class文件 ...

  4. STM32-开发环境搭建-STM32CubeMX-安装及配置

    STM32CubeMX系列教程之1.流水灯 刚刚接触到STM32CubeMX软件,感觉挺有意思,动动鼠标使STM32开发变得简单,特写文与大家分享.但具体性能如何还需测试. 硬件开发中的流水灯相当于软 ...

  5. ABAP和Java SpringBoot的单元测试

    ABAP 在ABAP类里,本地类(Local Class)里用关键字FOR TESTING声明过的方法, 在单元测试启动后会自动被调用到. Spring Boot 在Spring及Spring Boo ...

  6. Selenium入门系列5 默认不显示的下拉列表元素操作

    本节课程的下拉框是那种默认隐藏,当鼠标移到菜单上下拉框才显示的.如果直接getelement会报错,提示元素不可见: so,得先让下拉列表显示出来再获取元素 用到的新知识: is_display()  ...

  7. 【洛谷2605】[ZJOI2010] 基站选址(线段树维护DP)

    点此看题面 大致题意: 有\(n\)个村庄,每个村庄有\(4\)个属性:\(D_i\)表示与村庄\(1\)的距离,\(C_i\)表示建立基站的费用,\(S_i\)表示能将其覆盖的建基站范围,\(W_i ...

  8. nodejs的一些概念

    上一节我们几乎是扫通http请求和响应的整个闭环,包括请求时候的头信息和服务器返回时候的头信息和状态码等等,这些在node的http中都能获取到,并且有相应都接口组装这些信息和返回它们,同时这些htt ...

  9. UbuntuServer14.04+CUDA7.5+CuDNNv3+Caffe+OpenCV3.0+配置

    基本依赖项 sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial ...

  10. P1290 【欧几里德的游戏】

    P1290 [欧几里德的游戏] 真·做题全凭感性 从题目中很容易看出 这是一道\(Gcd\)的题 同时又结合了一些略略的博弈论(丢下锅跑真爽 我们看,辗转相减的\(a,b\)一共只有两种情况 \(a- ...