目的

实时监听某目录下的日志文件,如有新文件切换到新文件,并同步写入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. ComponentOne、Spread、ActiveReports 5折起 加入惊喜惠

    慧都十周年,GrapeCity也来共襄盛举,旗下三大产品产品线齐齐参与.界面控件套包ComponentOne.Excel表格控件Spread与报表开发工具ActiveReports,指定授权5折起加入 ...

  2. lrzsz的使用

    可以方便的在本地PC机和远程服务器之间传输文件. 1.下载 直接在centos上执行命令yum -y install lrzsz 2.上传文件 rz // 上传文件,执行命令rz,会跳出文件选择窗口, ...

  3. .net core 操作域控 活动目录 ladp -- Support for System.DirectoryServices for Windows

    原文链接:https://github.com/dotnet/corefx/issues/2089 1. @ianhays to kick start the project in CoreFX re ...

  4. OpenGL学习 Following the Pipeline

    Passing Data to the Vertex Shader Vertex Attributes At the start of the OpenGL pipeline,we use the i ...

  5. 【CSS古话今说】-- 01.神奇的CSS-BFC在实战中的应用

    文章首发于掘金 BFC(Block Formatting Context)是Web页面中盒模型布局的CSS渲染模式.它的定位体系属于常规文档流. 想要实现一个BFC布局需要满足以下条件之一: 1.fl ...

  6. 罗技G502设置

    这个鼠标默认内置了3个档案模式,用G9键来调节. p2 蓝色 1个灯 p2 蓝色 2个灯 p3 蓝色 3个灯 如此循环设置

  7. [转载]互联网 免费的WebService接口

    股票行情数据 WEB 服务(支持香港.深圳.上海基金.债券和股票:支持多股票同时查询) Endpoint: http://webservice.webxml.com.cn/WebServices/St ...

  8. POJ-3067 Japan---树状数组逆序对变形

    题目链接: https://vjudge.net/problem/POJ-3067 题目大意: 日本岛东海岸与西海岸分别有N和M个城市,现在修高速公路连接东西海岸的城市,求交点个数. 解题思路: 记每 ...

  9. The service command supports only basic LSB actions (start, stop, restart, try-restart, reload,force-reload, status)

    # service iptables save The service command supports only basic LSB actions (start, stop, restart, t ...

  10. 画X,模拟水题

    题目链接:http://codeforces.com/contest/404/problem/A #include <stdio.h> #include <string.h> ...