基于logminer 归档模式实现的日志分析

时光怂恿深爱的人放手 提交于 2020-10-14 19:47:19

1、为什么使用归档模式

     1)归档模式只要有磁盘,不会丢失数据,哪怕处理再慢也没关系。

     2)对性能的消耗最小。

package com.topnet.log.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.topnet.quick.frame.FastDao;
import com.topnet.quick.frame.OtherCondition;
import com.topnet.quick.frame.ds.DataSourceAnnotation;

@Service
@DataSourceAnnotation("logMiner")
public class LogMinerService {
  @Autowired
  FastDao fastDao;
  @Value("${log.scnFile}")
  String scnFile;

  public void get() {
    Long scn = getScn();
    while (true) {
      List<OtherCondition> otherConditions = new ArrayList<OtherCondition>();
      if (scn != null) {
        otherConditions.add(new OtherCondition("FIRST_CHANGE#", OtherCondition.GT, scn));
      }
      // 得到归档日志文件
      String archivedLogSql =
          "select sequence#, FIRST_CHANGE#, NEXT_CHANGE#,name from v$archived_log where name is not null";
      List<Map<String, Object>> ls =
          fastDao.findBySql(archivedLogSql, null, otherConditions, null, " sequence# ", 0, 3);
      if (ls.size() == 0) {
        break;
      }
      String build =
          "begin\n dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_location =>'/home/data/oracle');  \nend;";
      fastDao.execute(build);
      String app = "dbms_logmnr.new";
      Long firstChange = null;
      Long nextChange = null;
      for (Map<String, Object> map : ls) {
        // 记录第一给scn,和最后一个scn
        if (firstChange == null) {
          firstChange = Long.valueOf(map.get("firstChange#").toString());
        }
        nextChange = Long.valueOf(map.get("nextChange#").toString());
        String addFIle = "begin\n  dbms_logmnr.add_logfile('" + map.get("name").toString() + "',"
            + app + ");    \nend;";
        fastDao.execute(addFIle);
        app = "dbms_logmnr.addfile";
      }
      String start =
          "begin\n   dbms_logmnr.start_logmnr(dictfilename=>'/home/data/oracle/dictionary.ora'); \nend;  ";
      fastDao.execute(start);
      String sql = "SELECT scn, sql_redo, sql_undo   FROM v$logmnr_contents WHERE SEG_OWNER='LPF' ";
      String countSql = "SELECT count(*)   FROM v$logmnr_contents WHERE SEG_OWNER='LPF' ";
      Long n = fastDao.findCountByCustomSql(countSql, null, null, null);
      if (n == 0) {// 如果当前没有数据,那么就
        scn = nextChange;
        String end = "begin\n  DBMS_LOGMNR.END_LOGMNR ; \nend; ";
        fastDao.execute(end);
        writeScn(scn);
        continue;
      }
      int startNum = 0;
      int limit = 1000;
      while (startNum < n) {
        ls = fastDao.findBySql(sql, null, null, null, " scn  ", startNum, limit);
        for (Map<String, Object> map : ls) {
          scn = Long.valueOf(map.get("scn").toString());
          System.out.println(JSON.toJSON(map));
        }
        writeScn(scn);
        startNum = startNum + limit;
      }

      String end = "begin\n  DBMS_LOGMNR.END_LOGMNR ; \nend; ";
      fastDao.execute(end);
    }
  }

  /**
   * 手动归档
   */
  public void archive() {
    String sql = "alter system archive log current";
    fastDao.execute(sql);
  }

  /**
   * 得到当前scn号
   * 
   * @return
   */
  public Long getScn() {
    File f = new File(scnFile);
    if (!f.exists()) {
      return null;
    }
    BufferedReader br = null;
    try {
      br = new BufferedReader(new FileReader(f));
      String str = br.readLine();
      return Long.valueOf(str);
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      IOUtils.closeQuietly(br);
    }
    return null;
  }

  /**
   * 记录当前的scn号
   * 
   * @param scn
   */
  public void writeScn(Long scn) {
    File f = new File(scnFile);
    BufferedWriter bw = null;
    try {
      bw = new BufferedWriter(new FileWriter(f, false));
      bw.write(scn.toString());
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      IOUtils.closeQuietly(bw);
    }
  }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!