java读取用户登入退出日志信息上传服务端_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>

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java读取日志信息
svn服务端日志查看、svn服务端日志在哪里、服务端日志、触动精灵日志服务端、服务端日志格式规范,以便于您获取更多的相关知识。

时间: 2024-11-01 10:55:50

java读取用户登入退出日志信息上传服务端_java的相关文章

初学.NET的小菜鸟求救~~用户登入+信息查询问题………………急~十万火急

问题描述 老师要求做一个简单的住宅区里用的小页面~~~~是用VB.NET和ACCESS来做~~功能要求是--1,住户登入页面(账号为住户的门牌号,密码是户主的身份证号)2,登入后进入查询页面--说白了也就是一张表格--主要是查询住户上月由物业管理收缴的各项费用(卫生费,治安费,车位费等)和代缴的费用(水费电费煤气费等)3,管理员登入界面,登入后可以添加修改用户信息,以及收费信息.刚学.NET~~代码我不太懂,特别是数据库链接的问题~~~~~我同学说不用代码,LOGIN可以直接链接到数据库的--但

上传问题,如何在用户没有保存时删除已上传文件

问题描述 实际情况是:有一个web页面,用户可以新建教程.这个过程中用户可以上传相关的图片和文件,当用户点保存时,将文件路径写入数据库.问题是:如果用户一直上传,但最后却不点击保存,如何处理那些已上传的文件?(特别情况是用户打开了很多个页面,上传后都不保存)请各位发表意见... 解决方案 解决方案二:上传之后先保存在临时路径,保存的时候再把文件拷贝到正式路径如果没保存,就不用拷贝临时路径的文件最终都要删除----------------------------------------------

java socket手机通信-关于java的问题:手机用socket连接电脑的服务端时老出现文件找不到的错误,求解决

问题描述 关于java的问题:手机用socket连接电脑的服务端时老出现文件找不到的错误,求解决 30C 解决方案 也可以私聊我.扣扣1944687725 解决方案二: 解决方案三: 你那个斜杠是不是写反了 passwdinput.dat 解决方案四: 你仔细看看出错的提示, 是读文件的时候找不到,对应的代码是在ServerThread.java的51行然后,你把路径改为绝对路径试一试,如果可以了,就是你相对路径的根目录不对.保证passwd文件夹在你的执行目录下 解决方案五: 右键 prope

需求-java web 能够实现整个文件夹的上传下载吗?

问题描述 java web 能够实现整个文件夹的上传下载吗? 需求要上传下载文件夹,我感觉貌似是不能,求大神解惑,求!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 解决方案 如果要用java-web的话,个人感觉不可能,因为你的文件上传表单类型是file,只能选择文件. 但是如果要写的文件上传服务器的简单应用的话,是可以得使用FTPClient工具完成.类似文件上传工具FlashFXP软件的功能. 解决方案二: java web 实现上传下载 解决方案三: 没见过上传文

请问thrift 0.9.2 在大并发情况下能否保证先发出的信息能够被服务端先收到???

问题描述 请问thrift 0.9.2 在大并发情况下能否保证先发出的信息能够被服务端先收到??? 请问thrift 0.9.2 在大并发情况下能否保证先发出的信息能够被服务端先收到??? 最近在做一个服务端和客户端一致性的中间件,这个问题困扰好久,请大牛指点. 解决方案 这个应该没有保证,所以你需要服务端自己做优先级队列等 解决方案二: 谢谢,我再研究研究.

file zilla上传文件时退出之前已上传的照片会被保存吗?急求

问题描述 filezilla上传文件时退出之前已上传的照片会被保存吗? 解决方案 解决方案二:会的吧,只不过这个文件可能不完整.解决方案三:是什么样的不完整,打不开?

用户登入日志应该记录哪些内容 它的存储文件怎么弄

问题描述 如题..... 解决方案 日志嘛就负责记录xx于xx时间登入了系统呗,存储文件是什么意思?解决方案二:时间,ip,用户,浏览器类型或设备等等,根据自己需要添加解决方案三:按day分割文件呗

java实现分段读取文件并通过HTTP上传的方法_java

本文实例讲述了java实现分段读取文件并通过HTTP上传的方法.分享给大家供大家参考.具体如下: 1.首先将文件分段,用RandomAccessFile 2.分段后将分出的内容上传到http URL url = new URL(actionUrl); HttpURLConnection con = (HttpURLConnection) url.openConnection(); /** 允许Input.Output,不使用Cache */ con.setDoInput(true); con.s

java读取wav文件(波形文件)并绘制波形图的方法_java

本文实例讲述了java读取wav文件(波形文件)并绘制波形图的方法.分享给大家供大家参考.具体如下: 因为最近有不少网友询问我波形文件读写方面的问题,出于让大家更方便以及让代码能够得到更好的改进,我将这部分(波形文件的读写)代码开源在GitHub上面. 地址为https://github.com/sintrb/WaveAccess/,最新的代码.例子.文档都在那上面,我会在我时间精力允许的前提下对该项目进行维护,同时也希望对这方面有兴趣的网友能够加入到该开源项目上. 以下内容基本都过期了,你可以