java读取用户登入退出日志信息上传服务端

本文实例为大家分享了读取用户登入出日志并上传服务端的具体实现代码,供大家参考,具体内容如下

该客户端运行在给用户提供unix服务的服务器上。用来读取并收集该服务器上用户的上下线信息,并进行配对整理后发送给服务端汇总。

具体实现代码:

1. DMSServer.java

package com.dms;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * DMS服务端,用来接收每个客户端发送过来的
 * 配对日志并保存在本地文件中
 * @author Administrator
 *
 */
public class DMSServer {
  //属性定义
  //用来接收客户端连接的服务端的ServerSocket
  private ServerSocket server;
  //用来管理处理客户端请求的线程的线程池
  private ExecutorService threadPool;
  //保存所有客户端发送过来配对日志的文件
  private File serverLogFile;
  //消息队列
  private BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();

  public DMSServer() throws Exception{
    try {
      System.out.println("服务端正在初始化...");
      //1 解析配置文件server-config.xml
      Map<String,String> config = loadConfig();

      //2 根据配置文件内容初始化属性
      init(config);
      System.out.println("服务端初始化完毕...");
    } catch (Exception e) {
      System.out.println("初始化服务端失败!");
      throw e;
    }
  }

  /**
   * 构造方法初始化第一步,解析配置文件
   * @return 返回的Map中保存的是配置文件中的
   *     每一条内容,其中key:标签的名字,
   *     value为标签中间的文本
   * @throws Exception
   */
  private Map<String,String> loadConfig() throws Exception{
    try {
      SAXReader reader = new SAXReader();
      Document doc
        = reader.read(new File("server-config.xml"));
      Element root = doc.getRootElement();

      Map<String,String> config
        = new HashMap<String,String>();
      /*
       * 获取<config>标签中的所有子标签
       * 并将每一个子标签的名字作为key,中间的
       * 文本作为value存入Map集合
       */
      List<Element> list = root.elements();
      for(Element e : list){
        String key = e.getName();
        String value = e.getTextTrim();
        config.put(key, value);
      }
      return config;
    } catch (Exception e) {
      System.out.println("解析配置文件异常!");
      e.printStackTrace();
      throw e;
    }
  }

  /**
   * 构造方法初始化第二步,根据配置项初始化属性
   * @param config
   * @throws Exception
   */
  private void init(Map<String,String> config) throws Exception{
    /*
     * 用配置文件中的<logrecfile>初始化属性:serverLogFile
     * 用配置文件中的<threadsum>初始化属性:threadPool,这里创建固定大小线程池。该值作为线程池线程数量
     * 用配置文件中的<serverport>初始化属性:server,这里这个值为ServerSocket的服务端口
     */
    this.server = new ServerSocket(
      Integer.parseInt(config.get("serverport"))
    );

    this.serverLogFile = new File(
      config.get("logrecfile")
    );
    this.threadPool = Executors.newFixedThreadPool(
      Integer.parseInt(config.get("threadsum"))
    );
  }
  /**
   * 服务端开始工作的方法
   * @throws Exception
   */
  public void start() throws Exception{
    /*
     * 实现要求:
     * 首先单独启动一个线程,用来运行SaveLogHandler
     * 这个任务,目的是保存所有配对日志
     * 然后开始循环监听服务端端口,一旦一个客户端连接了,
     * 就实例化一个ClientHander,然后将该任务交给线程池
     * 使其分配线程来处理与该客户端的交互。
     *
     */
    try {
      System.out.println("服务端开始工作...");
      SaveLogHandler slh=new SaveLogHandler();
      new Thread(slh).start();

      while(true){
        Socket socket=server.accept();

        threadPool.execute(new ClientHandler(socket));
      }

    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
  }

  public static void main(String[] args) {
    try {
      DMSServer server = new DMSServer();
      server.start();
    } catch (Exception e) {
      System.out.println("启动服务端失败!");
    }
  }
  /**
   * 该线程负责从消息队列中取出每一条配对日志,
   * 并存入到serverLogFile文件
   * @author Administrator
   *
   */
  private class SaveLogHandler implements Runnable{
    public void run(){
      PrintWriter pw = null;
      try {
        pw = new PrintWriter(
          new FileOutputStream(
            serverLogFile,true
          )
        );
        while(true){
          if(messageQueue.size()>0){
            pw.println(messageQueue.poll());
          }else{
            pw.flush();
            Thread.sleep(500);
          }
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally{
        if(pw != null){
          pw.close();
        }
      }
    }
  }

  /**
   * 处理一个指定客户端请求
   * @author Administrator
   *
   */
  private class ClientHandler implements Runnable{
    private Socket socket;
    public ClientHandler(Socket socket){
      this.socket = socket;
    }
    public void run(){
      /*
       * 思路:
       * 首先接收客户端发送过来的所有配对日志,
       * 直到读取到"OVER"为止,然后将这些配对
       * 日志保存到本地的文件中,并回复客户端
       * "OK"
       * 执行步骤:
       * 1:通过Socket创建输出流,用来给客户端
       *  发送响应
       * 2:通过Socket创建输入流,读取客户端发送
       *  过来的日志
       * 3:循环读取客户端发送过来的每一行字符串,并
       *  先判断是否为字符串"OVER",若不是,则是
       *  一条配对日志,那么保存到本地文件,若是,
       *  则停止读取。
       * 4:成功读取所有日志后回复客户端"OK"
       */
      PrintWriter pw = null;
      try {
        //1
        pw = new PrintWriter(
          new OutputStreamWriter(
            socket.getOutputStream(),"UTF-8"
          )
        );
        //2
        BufferedReader br = new BufferedReader(
          new InputStreamReader(
            socket.getInputStream(),"UTF-8"
          )
        );

        //3
        String message = null;
        while((message = br.readLine())!=null){
          if("OVER".equals(message)){
            break;
          }
          //将该日志写入文件保存
          messageQueue.offer(message);
        }

        //4
        pw.println("OK");
        pw.flush();

      } catch (Exception e) {
        e.printStackTrace();
        pw.println("ERROR");
        pw.flush();
      } finally{
        try {
          //与客户端断开连接释放资源
          socket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
}

2. DMSClient.java

package com.dms;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.dms.bo.LogData;
import com.dms.bo.LogRec;

/**
 * 该客户端运行在给用户提供unix服务的服务器上。
 * 用来读取并收集该服务器上用户的上下线信息,并
 * 进行配对整理后发送给服务端汇总。
 * @author Administrator
 *
 */
public class DMSClient {
  //属性定义

  //第一步:解析日志所需属性
  //unix系统日志文件
  private File logFile;
  //保存解析后日志的文件
  private File textLogFile;
  //书签文件
  private File lastPositionFile;
  //每次解析日志的条目数
  private int batch;

  //第二步:配对日志所需要属性
  //保存配对日志的文件
  private File logRecFile;
  //保存未配对日志的文件
  private File loginLogFile;

  //第三步:发送日志所需要属性
  //服务端地址
  private String serverHost;
  //服务端端口
  private int serverPort;

  /**
   * 构造方法,用来初始化客户端
   * @throws Exception
   */
  public DMSClient() throws Exception{
    try {
      //1 解析配置文件config.xml
      Map<String,String> config = loadConfig();
      //打桩
      System.out.println(config);

      //2 根据配置文件内容初始化属性
      init(config);

    } catch (Exception e) {
      System.out.println("初始化失败!");
      throw e;
    }
  }
  /**
   * 构造方法初始化第二步,根据配置项初始化属性
   * @param config
   * @throws Exception
   */
  private void init(Map<String,String> config) throws Exception{
    try {
      logFile = new File(
        config.get("logfile")
      );
      textLogFile = new File(
        config.get("textlogfile")
      );
      lastPositionFile = new File(
        config.get("lastpositionfile")
      );
      batch = Integer.parseInt(
        config.get("batch")
      );
      logRecFile = new File(
        config.get("logrecfile")
      );
      loginLogFile = new File(
        config.get("loginlogfile")
      );
      serverHost = config.get("serverhost");
      serverPort = Integer.parseInt(
        config.get("serverport")
      );     

    } catch (Exception e) {
      System.out.println("初始化属性失败!");
      e.printStackTrace();
      throw e;
    }
  }

  /**
   * 构造方法初始化第一步,解析配置文件
   * @return 返回的Map中保存的是配置文件中的
   *     每一条内容,其中key:标签的名字,
   *     value为标签中间的文本
   * @throws Exception
   */
  private Map<String,String> loadConfig() throws Exception{
    try {
      SAXReader reader = new SAXReader();
      Document doc
        = reader.read(new File("config.xml"));
      Element root = doc.getRootElement();

      Map<String,String> config
        = new HashMap<String,String>();
      /*
       * 获取<config>标签中的所有子标签
       * 并将每一个子标签的名字作为key,中间的
       * 文本作为value存入Map集合
       */
      List<Element> list = root.elements();
      for(Element e : list){
        String key = e.getName();
        String value = e.getTextTrim();
        config.put(key, value);
      }
      return config;
    } catch (Exception e) {
      System.out.println("解析配置文件异常!");
      e.printStackTrace();
      throw e;
    }
  }

  /**
   * 客户端开始工作的方法
   * 循环执行三步:
   * 1:解析日志
   * 2:配对日志
   * 3:发送日志
   */
  public void start(){
    parseLogs();
    matchLogs();
    sendLogs();
//   while(true){
//     //解析日志
//     if(!parseLogs()){
//       continue;
//     }
//     //配对日志
//     if(!matchLogs()){
//       continue;
//     }
//     //发送日志
//     sendLogs();
//   }
  }
  /**
   * 第三步:发送日志
   * @return true:发送成功
   *     false:发送失败
   */
  private boolean sendLogs(){
      /*
       * 实现思路:
       * 将logRecFile文件中的所有配对日志读取
       * 出来然后连接上服务端并发送过去,若服务端
       * 全部接收,就可以将该文件删除,表示发送
       * 完毕了。
       * 实现步骤:
       * 1:logRecFile文件必须存在
       * 2:将所有配对日志读取出来并存入一个集合
       *  等待发送
       * 3:通过Socket连接服务端
       * 4:创建输出流
       * 5:顺序将所有配对日志按行发送给服务端
       * 6:单独发送一个字符串"OVER"表示所有日志
       *  均已发送完毕
       * 7:创建输入流
       * 8:读取服务端发送回来的响应字符串
       * 9:若响应的字符串为"OK",表示服务端正常
       *  接收了所有日志,这时就可以将logRecFile
       *  文件删除并返回true表示发送完毕。
       *
       */
    Socket socket = null;
    try {
      //1
      if(!logRecFile.exists()){
        System.out.println(logRecFile+"不存在!");
        return false;
      }
      //2
      List<String> matches
        = IOUtil.loadLogRec(logRecFile);

      //3
      socket = new Socket(serverHost,serverPort);

      //4
      PrintWriter pw = new PrintWriter(
        new OutputStreamWriter(
          socket.getOutputStream(),"UTF-8"
        )
      );

      //5
      for(String log : matches){
        pw.println(log);
      }

      //6
      pw.println("OVER");
      pw.flush();

      //7
      BufferedReader br = new BufferedReader(
        new InputStreamReader(
          socket.getInputStream(),"UTF-8"
        )
      );

      //8
      String response = br.readLine();
      //9
      if("OK".equals(response)){
        logRecFile.delete();
        return true;
      }else{
        System.out.println("发送日志失败!");
        return false;
      }

    } catch (Exception e) {
      System.out.println("发送日志失败!");
      e.printStackTrace();
    } finally{
      if(socket != null){
        try {
          socket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return false;
  }

  /**
   * 第二步:配对日志
   * @return true:配对成功
   *     false:配对失败
   */
  private boolean matchLogs(){

      /*
       * 实现思路:
       * 将第一步解析的新日志,与上次为配对成功
       * 的登入日志全部读取出来,然后再按照user,
       * pid相同,type一个是7,一个是8进行配对。
       * 只要能找到类型为8的,一定可以找到一个
       * 能与之配对的登入日志。
       *
       * 实现步骤:
       * 1:必要的判断
       *  1.1:logRecFile是否存在,存在则不再
       *    进行新的配对工作,避免覆盖。
       *  1.2:textLogFile文件必须存在。
       * 2:读取textLogFile将日志读取出来,并
       *  存入到集合中。(若干LogData实例)
       * 3:若loginLogFile文件若存在,则说明
       *  有上次未配对成功的日志,也将其读取
       *  出来存入集合等待一起配对
       * 4:配对工作
       *  4.1:创建一个集合,用于保存所有配对日志
       *  4.2:创建两个Map分别保存登入日志与登出日志
       *  4.3:遍历所有待配对的日志,按照登入与登出
       *    分别存入两个Map中,
       *    其中key:user,pid
       *      value:LogData实例
       *  4.4:遍历登出Map,并根据每条登出日志的key
       *    去登入Map中找到对应的登入日志,并
       *    以一个LogRec实例保存该配对日志,然后
       *    存入配对日志的集合中。并将该配对日志
       *    中的登入日志从登入Map中删除。这样一来
       *    登入Map中应当只剩下没有配对的了。
       * 5:将配对日志写入到logRecFile中
       * 6:将所有未配对日志写入到loginLogFile中
       * 7:将textLogFile文件删除
       * 8:返回true,表示配对完毕
       *
       */
    try {
      //1
      //1.1
      if(logRecFile.exists()){
        return true;
      }
      //1.2
      if(!textLogFile.exists()){
        System.out.println(textLogFile+"不存在!");
        return false;
      }

      //2
      List<LogData> list
        = IOUtil.loadLogData(textLogFile);

      //3
      if(loginLogFile.exists()){
        list.addAll(
          IOUtil.loadLogData(loginLogFile)
        );
      }

      //4
      //4.1
      List<LogRec> matches
        = new ArrayList<LogRec>();
      //4.2
      Map<String,LogData> loginMap
        = new HashMap<String,LogData>();
      Map<String,LogData> logoutMap
        = new HashMap<String,LogData>();

      //4.3
      for(LogData logData : list){
        String key = logData.getUser()+","+
              logData.getPid();
        if(logData.getType()==LogData.TYPE_LOGIN){
          loginMap.put(key, logData);
        }else  if(logData.getType()==LogData.TYPE_LOGOUT){
          logoutMap.put(key, logData);
        }
      }

      //4.4
      Set<Entry<String,LogData>> entrySet
          = logoutMap.entrySet();
      for(Entry<String,LogData> e : entrySet){
        LogData logout = e.getValue();
        LogData login = loginMap.remove(e.getKey());
        LogRec logRec = new LogRec(login,logout);
        matches.add(logRec);
      }

      //5
      IOUtil.saveCollection(matches, logRecFile);

      //6
      IOUtil.saveCollection(
          loginMap.values(),loginLogFile
      );

      //7
      textLogFile.delete();

      //8
      return true;

    } catch (Exception e) {
      System.out.println("配对日志失败!");
      e.printStackTrace();
    }
    return false;
  }

  /**
   * 第一步:解析日志
   * @return true:解析成功
   *     false:解析失败
   */
  private boolean parseLogs(){
    /*
     * 实现思路:
     * 循环读取batch条日志,然后将每条日志中的
     * 5个信息解析出来,最终组成一个字符串,以
     * 行为单位,写入到textLogFile文件中
     *
     * 实现步骤:
     * 1:必要的判断工作
     *  1.1:为了避免解析的日志还没有被使用,而
     *    第一步又重复执行导致之前日志被覆盖
     *    的问题,这里需要判断,若保存解析后
     *    的日志文件存在,则第一步不再执行。
     *    该日志文件会在第二步配对完毕后删除。
     *  1.2:logFile文件必须存在(wtmpx文件)
     *  1.3:是否还有日志可以解析
     * 2:创建RandomAccessFile来读取logFile
     * 3:将指针移动到上次最后读取的位置,准备
     *  开始新的解析工作
     * 4:解析工作
     *  4.1:创建一个List集合,用于保存解析后
     *    的每一条日志(LogData实例)
     *  4.2:循环batch次,解析每条日志中的
     *    5项内容(user,pid,type,time,host)
     *    并用一个LogData实例保存,然后将
     *    该LogData实例存入集合
     * 5:将集合中的所有的日志以行为单位保存到
     *  textLogFile中
     * 6:保存书签信息
     * 7:返回true,表示工作完毕
     *
     */
    RandomAccessFile raf = null;
    try {
      //1
      //1.1
      if(textLogFile.exists()){
        return true;
      }

      //1.2
      if(!logFile.exists()){
        System.out.println(logFile+"不存在!");
        return false;
      }
      //1.3
      long lastPosition = hasLogs();
      //打桩
//     System.out.println(
//         "lastPosition:"+lastPosition
//     );

      if(lastPosition<0){
        System.out.println("没有日志可以解析了!");
        return false;
      }

      //2
      raf = new RandomAccessFile(logFile,"r");

      //3
      raf.seek(lastPosition);

      //4
      List<LogData> list
        = new ArrayList<LogData>();
      for(int i=0;i<batch;i++){
        //每次解析前都判断是否还有日志可以解析
        if(logFile.length()-lastPosition
            <LogData.LOG_LENGTH
        ){
          break;
        }
        //解析user
        raf.seek(lastPosition+LogData.USER_OFFSET);
        String user
          = IOUtil.readString(
              raf, LogData.USER_LENGTH
            ).trim();

        //解析PID
        raf.seek(lastPosition+LogData.PID_OFFSET);
        int pid = raf.readInt();

        //解析TYPE
        raf.seek(lastPosition+LogData.TYPE_OFFSET);
        short type = raf.readShort();

        //解析TIME
        raf.seek(lastPosition+LogData.TIME_OFFSET);
        int time = raf.readInt();

        //解析HOST
        raf.seek(lastPosition+LogData.HOST_OFFSET);
        String host
          = IOUtil.readString(
              raf, LogData.HOST_LENGTH
            ).trim();

        LogData log = new LogData(user, pid, type, time, host);

        list.add(log);
        //打桩
//       System.out.println(log);

        //当解析完一条日志后,更新lastPosition
        lastPosition = raf.getFilePointer();
      }

      //5
      IOUtil.saveCollection(list, textLogFile);

      //6 保存书签文件
      IOUtil.saveLong(
          lastPosition, lastPositionFile);

      //7
      return true;

    } catch (Exception e) {
      System.out.println("解析日志失败!");
      e.printStackTrace();
    } finally{
      if(raf != null){
        try {
          raf.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

    return false;
  }
  /**
   * 第一步解析日志中的一个环节,
   * 根据书签文件记录的位置判断是否还有
   * 日志可以解析,若有,则将上次最后的位置
   * 返回,若没有则返回-1。
   * @return
   */
  private long hasLogs(){
    try {
      /*
       * 若lastPositionFile不存在,则说明
       * 从来没有解析过,那么从头开始解析即可
       */
      if(!lastPositionFile.exists()){
        return 0;
      }

      long lastPosition
        = IOUtil.readLong(lastPositionFile);

      if(logFile.length()-lastPosition
          >=LogData.LOG_LENGTH){
        return lastPosition;
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
    return -1;
  }

  public static void main(String[] args) {
    try {
      DMSClient client = new DMSClient();
      client.start();
    } catch (Exception e) {
      System.out.println("客户端运行失败!");
    }
  }
}

3. IOUtil.java

package com.dms;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.dms.bo.LogData;

/**
 * 该类是一个工具类,负责客户端的IO操作
 * @author Administrator
 *
 */
public class IOUtil {
  /**
   * 从给定的文件中读取每一行字符串(配对日志)
   * 并存入一个集合后返回
   * @param file
   * @return
   * @throws Exception
   */
  public static List<String> loadLogRec(File file) throws Exception{
    BufferedReader br = null;
    try {
      br = new BufferedReader(
        new InputStreamReader(
          new FileInputStream(
            file
          )
        )
      );
      List<String> list
        = new ArrayList<String>();
      String line = null;
      while((line = br.readLine())!=null){
        list.add(line);
      }
      return list;
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    } finally{
      if(br != null){
        br.close();
      }
    }
  }
  /**
   * 从给定的文件中读取每一条配对日志,并存入
   * 一个集合中然后返回。
   * @param file
   * @return
   * @throws Exception
   */
  public static List<LogData> loadLogData(File file) throws Exception{
    BufferedReader br = null;
    try {
      br = new BufferedReader(
        new InputStreamReader(
          new FileInputStream(
            file
          )
        )
      );
      List<LogData> list = new ArrayList<LogData>();
      String line = null;
      while((line = br.readLine())!=null){
        LogData logData = new LogData(line);
        list.add(logData);
      }
      return list;
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    } finally{
      if(br!=null){
        br.close();
      }
    }
  }

  /**
   * 将指定的long值以字符串的形式写入到
   * 给定文件的第一行
   * @param l
   * @param file
   * @throws Exception
   */
  public static void saveLong(
          long lon,File file) throws Exception{
    PrintWriter pw = null;
    try {
      pw = new PrintWriter(file);
      pw.println(lon);
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    } finally{
      if(pw != null){
        pw.close();
      }
    }
  }

  /**
   * 将集合中每个元素的toString方法返回的字符串
   * 以行为单位写入到指定文件中。
   * @param c
   * @param file
   * @throws Exception
   */
  public static void saveCollection(
                Collection c,File file) throws Exception{
    PrintWriter pw = null;
    try {
      pw = new PrintWriter(file);
      for(Object o : c){
        pw.println(o);
      }
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    } finally{
      if(pw != null){
        pw.close();
      }
    }
  }

  /**
   * 从给定的RandomAccessFile当前位置开始连续
   * 读取length个字节,并转换为字符串后返回
   * @param raf
   * @param length
   * @return
   * @throws Exception
   */
  public static String readString(
          RandomAccessFile raf,int length) throws Exception{
    try {
      byte[] data = new byte[length];
      raf.read(data);
      return new String(data,"ISO8859-1");
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
  }

  /**
   * 从给定文件中读取第一行字符串,然后将其
   * 转换为一个long值后返回
   * @param file
   * @return
   * @throws Exception
   */
  public static long readLong(File file) throws Exception{
    BufferedReader br = null;
    try {
      br = new BufferedReader(
        new InputStreamReader(
          new FileInputStream(
            file
          )
        )
      );
      String line = br.readLine();
      return Long.parseLong(line);
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    } finally{
      if(br != null){
        br.close();
      }
    }
  }
}

4. config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <!-- unix系统日志文件名 -->
  <logfile>wtmpx</logfile>
  <!-- 保存解析后日志的文件名 -->
  <textlogfile>log.txt</textlogfile>
  <!-- 书签文件名 -->
  <lastpositionfile>last-position.txt</lastpositionfile>
  <!-- 每次解析日志的条目数 -->
  <batch>10</batch>
  <!-- 配对日志文件名 -->
  <logrecfile>logrec.txt</logrecfile>
  <!-- 未配对日志文件名 -->
  <loginlogfile>login.txt</loginlogfile>
  <!-- 服务端地址 -->
  <serverhost>localhost</serverhost>
  <!-- 服务端端口 -->
  <serverport>8088</serverport>
</config>

5.  server-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <!-- 服务端保存配对日志文件的文件名 -->
  <logrecfile>server-logs.txt</logrecfile>
  <!-- 线程池线程数量 -->
  <threadsum>30</threadsum>
  <!-- 服务端端口 -->
  <serverport>8088</serverport>
</config>

以上就是本文的全部内容,希望对大家的学习有所帮助。

(0)

相关推荐

  • 自己写的简易版Java日志类分享

    /** * */ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; /** * @author magic282 * */ public class Logger { private static String logFilePath; private static boolean

  • java使用动态代理来实现AOP(日志记录)的实例代码

    下面是一个AOP实现的简单例子: 首先定义一些业务方法: 复制代码 代码如下: /** * Created with IntelliJ IDEA. * Author: wangjie  email:tiantian.china.2@gmail.com * Date: 13-9-23 * Time: 下午3:49 */public interface BussinessService {    public String login(String username, String password

  • Log4j定时打印日志及添加模块名配置的Java代码实例

    配置间隔时间,定时打印日志  接到个需求,通过log4j定时打印日志,需求描述如下:需要能够定时打印日志,时间间隔可配.说到定时,首先想到了DailyRollingFileAppender类,各种定时,根据datePattern,这个可以参考类SimpleDateFormat类,常见的一些定时设置如下: '.'yyyy-MM: 每月 '.'yyyy-ww: 每周 '.'yyyy-MM-dd: 每天 '.'yyyy-MM-dd-a: 每天两次 '.'yyyy-MM-dd-HH: 每小时 '.'yy

  • Java中重定向输出流实现用文件记录程序日志

    System中的out,error都是final类型的,不能做改动.但通过setOut()可以设置新的输出流,从而实现写日志的功能. import java.io.PrintStream; import java.io.FileNotFoundException; public class RedirectOutputStream { public static void main(String arg[]){ try{ PrintStream out = System.out; //保留原输出

  • java自定义日志输出文件(log4j日志文件输出多个自定义日志文件)

    log4j输出多个自定义日志文件 如果在实际应用中需要输出独立的日志文件,怎样才能把所需的内容从原有日志中分离,形成单独的日志文件呢? 先看一个常见的log4j.properties文件,它是在控制台和test.log文件中记录日志: 复制代码 代码如下: log4j.rootLogger=DEBUG, stdout, logfile log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layo

  • Java日志软件Log4j的基本使用教程

    1.概述 1.1背景 在我们的日常开发中,日志记录非常重要.在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作:跟踪代码运行时轨迹,作为日后审计的依据:担当集成开发环境中的调试器的作用,向文件或控制台打印代码的调试信息. 1.2简介 Log4j(log for java)是Apache的一个开放源代码项目,它提供了一种细腻的日志管理方式.通过一个配置文件,我们可以多选择的控制每条日志的输出格式和目的地.通过定义信息的级别,我们也

  • Java 调整格式日志输出

    工欲善其事,必先利其器 很多程序员可能都忘了记录应用程序的行为是一件多么重要的事,当遇到多线程环境下高压力导致的并发bug时,你就能体会到记录log的重要性. 有的人很高兴的就在代码里加上了这么句: log.info("Happy and carefree logging"); 他可能都没有意识到应用程序的日志在维护,调优和故障识别中的重要性.我认为slf4j是最好的日志API,最主要是因为它支持一个很棒的模式注入的方式: log.debug("Found {} record

  • 使用java实现日志工具类分享

    复制代码 代码如下: package com.teligen.eos.teleCode; import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.util.Date; /** * 书写日志信息到指定的文件中 */public class WriteLogUtil { private static String rootPath = "D:\\logs\\"; /**  *

  • 自己写的java日志类和方法代码分享

    复制代码 代码如下: import java.io.*;import java.text.SimpleDateFormat;import java.util.*;import java.util.logging.Logger; public class AndyLogger{    //The defaulted root path of SSLVPN installation     private static String rootPath = "C:\\temp2"; //va

  • java读取用户登入退出日志信息上传服务端

    本文实例为大家分享了读取用户登入出日志并上传服务端的具体实现代码,供大家参考,具体内容如下 该客户端运行在给用户提供unix服务的服务器上.用来读取并收集该服务器上用户的上下线信息,并进行配对整理后发送给服务端汇总. 具体实现代码: 1. DMSServer.java package com.dms; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.i

  • python编辑用户登入界面的实现代码

    1.需求分析 登入界面需要达到以下要求: 系统要有登入和注册两个选项可供选择 系统要能够实现登入出错提示,比如账户密码错误等,用户信息保存在user_info.txt文件夹中 系统要能够进行登入错误次数统计并锁定,当用户输入3次错误时账户密码时,改账户被锁定,并将锁定账户保存于login_lock.txt文件夹中 注册界面要能够进行用户名重复提示,当用户注册账户已存在时,进行相应信息的提示. 1.代码实现 getNum = int(input("1.登入\n2.注册\nPlease Input

  • webuploader在springMVC+jquery+Java开发环境下的大文件分片上传的实例代码

    注意: 1,webuploader上传组件会和jQuery自带的上传组件冲突,所以不要使用<form>标签中添加上传文件的属性; enctype="multipart/form-data" 2.并且屏蔽ApplicationContext-mvc.xml里面的拦截配置! <!-- 上传拦截,如最大上传值及最小上传值 --> <!--新增加的webuploader上传组件,必须要屏蔽这里的拦截机制 <bean id="multipartRes

  • Java实现FTP文件与文件夹的上传和下载

    FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(Application).基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件.在FTP的使用当中,用户经常遇到两个概念:"下载"(Download)和"上传"(Upload)."下载"文件就是从远程主机拷贝文件至自己

  • Java FtpClient 实现文件上传服务

    一.Ubuntu 安装 Vsftpd 服务 1.安装 sudo apt-get install vsftpd 2.添加用户(uftp) sudo useradd -d /home/uftp -s /bin/bash uftp 3.设置用户密码 sudo useradd -d /home/uftp -s /bin/bash uftp 4.创建用户目录 sudo mkdir /home/uftp 5.设置用户密码 sudo passwd uftp 6.设置/etc/vsftpd.conf配置文件 s

  • java基于servlet使用组件smartUpload实现文件上传

    文件上传在web应用中是非常常见的,现在我就介绍下基于servlet的文件上传,基于Struts2的文件上传可以看: 页面端代码: <%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <ht

  • Java Web使用Html5 FormData实现多文件上传功能

    前一阵子,迭代一个线上的项目,其中有一个图片上传的功能,之前用的ajaxfileupload.js来实现上传的,不过由于ajaxfileupload.js,默认是单文件上传(虽然可以通过修改源码的方法来实现多文件上传),又加上是在移动端做的,所以就打算采用html5的FormData实现多文件上传 首先html页面定义有两种: Html1 <form enctype="multipart/form-data" id="formfile"> <inp

  • java客户端线上Apollo服务端的实现

    1.指定环境 1.1 在C:\opt\settings\下有server.properties env=DEV是对应服务器上的如下图 apollo.meta=http://192.168.1.143:8070是你服务端的端口号   1.2 在C:\opt\data\babel023\config-cache有这四个文件 2.在META-INF下创建app.properties app.properties下的内容app.id对应Apollo服务端的id 3.创建个SimpleApolloConf

  • Java中使用内存映射实现大文件上传实例

    在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验. 复制代码 代码如下: package test; import java.io.BufferedInputStream;  import java.io.FileInputStream;  import java.io.FileNotFoundException;  import

  • java如何获取用户登录ip、浏览器信息、SessionId

    目录 java获取用户登录ip.浏览器信息.SessionId 1.获取用户登录ip 2.获取用户所使用的浏览器信息 3.获取用户SessionId 获取用户登录的ip地址(考虑多种请求头的情况) java获取用户登录ip.浏览器信息.SessionId 1.获取用户登录ip //获取用户登录ip; String loginIp = request.getHeader("X-Forwarded-For"); if (loginIp == null || loginIp.length()

随机推荐