• Hadoop MapReduce Task Log 无法查看syslog问题


    现象:

    由于多个map task共用一个JVM,所以只输出了一组log文件

    datanode01:/data/hadoop-x.x.x/logs/userlogs$ ls -R

    .:

    attempt_201211220735_0001_m_000000_0  attempt_201211220735_0001_m_000002_0  attempt_201211220735_0001_m_000005_0

    attempt_201211220735_0001_m_000001_0  attempt_201211220735_0001_m_000003_0

    ./attempt_201211220735_0001_m_000000_0:

    log.index

    ./attempt_201211220735_0001_m_000001_0:

    log.index

    ./attempt_201211220735_0001_m_000002_0:

    log.index  stderr  stdout  syslog

    通过http://xxxxxxxx:50060/tasklog?attemptid= attempt_201211220735_0001_m_000000_0 获取task的日志时,会出现syslog无法获取

    原因:

    1.TaskLogServlet.doGet()方法

    if (filter == null) {
            printTaskLog(response, out, attemptId,start, end, plainText,
                         TaskLog.LogName.STDOUT,isCleanup);
            printTaskLog(response, out, attemptId,start, end, plainText,
                         TaskLog.LogName.STDERR,isCleanup);
            if(haveTaskLog(attemptId, isCleanup, TaskLog.LogName.SYSLOG)) {
              printTaskLog(response, out,attemptId, start, end, plainText,
                  TaskLog.LogName.SYSLOG,isCleanup);
            }
            if(haveTaskLog(attemptId, isCleanup, TaskLog.LogName.DEBUGOUT)) {
              printTaskLog(response, out,attemptId, start, end, plainText,
                           TaskLog.LogName.DEBUGOUT, isCleanup);
            }
            if(haveTaskLog(attemptId, isCleanup, TaskLog.LogName.PROFILE)) {
              printTaskLog(response, out,attemptId, start, end, plainText,
                           TaskLog.LogName.PROFILE,isCleanup);
            }
          } else {
            printTaskLog(response, out, attemptId,start, end, plainText, filter,
                         isCleanup);
         }

    尝试将filter=SYSLOG参数加上,可以访问到syslog,但去掉就不行。

    看了代码多了一行

    haveTaskLog(attemptId, isCleanup,TaskLog.LogName.SYSLOG)

    判断,跟进代码发现,检查的是原来

    attempt_201211220735_0001_m_000000_0目录下是否有syslog文件?

    而不是从log.indexlocation看是否有syslog文件,一个bug出现了!

     

    2.TaskLogServlet. printTaskLog方法

    获取日志文件时会从log.index读取。

     

    InputStreamtaskLogReader =
           new TaskLog.Reader(taskId,filter, start, end, isCleanup);
    TaskLog.Reader
    public Reader(TaskAttemptIDtaskid, LogName kind,
                      long start,long end, boolean isCleanup) throwsIOException {
          // find the right log file
          Map<LogName, LogFileDetail>allFilesDetails =
             getAllLogsFileDetails(taskid, isCleanup);
     
    static Map<LogName, LogFileDetail> getAllLogsFileDetails(
          TaskAttemptID taskid, booleanisCleanup) throws IOException {
     
        Map<LogName, LogFileDetail>allLogsFileDetails =
            newHashMap<LogName, LogFileDetail>();
     
        File indexFile = getIndexFile(taskid,isCleanup);
        BufferedReader fis;
        try {
          fis = newBufferedReader(new InputStreamReader(
            SecureIOUtils.openForRead(indexFile,obtainLogDirOwner(taskid))));
        } catch(FileNotFoundException ex) {
          LOG.warn("Index file for the log of " + taskid + " does not exist.");
     
          //Assume no task reuse is used and files exist on attemptdir
          StringBuffer input = newStringBuffer();
          input.append(LogFileDetail.LOCATION
                         + getAttemptDir(taskid,isCleanup) + "
    ");
          for(LogName logName : LOGS_TRACKED_BY_INDEX_FILES) {
            input.append(logName + ":0 -1
    ");
          }
          fis = newBufferedReader(new StringReader(input.toString()));
    }
    ………………….


    问题解决:

    类似getAllLogsFileDetails一样,先从log.index获取日志目录获取logdir,

       

     File indexFile = getIndexFile(taskid,isCleanup);
        BufferedReader fis;
        try {
          fis = newBufferedReader(new InputStreamReader(
            SecureIOUtils.openForRead(indexFile,obtainLogDirOwner(taskid))));
        } catch(FileNotFoundException ex) {
          LOG.warn("Index file for the log of " + taskid + " does not exist.");
     
          //Assume no task reuse is used and files exist on attemptdir
          StringBuffer input = newStringBuffer();
          input.append(LogFileDetail.LOCATION
                         + getAttemptDir(taskid,isCleanup) + "
    ");
          for(LogName logName : LOGS_TRACKED_BY_INDEX_FILES) {
            input.append(logName + ":0 -1
    ");
          }
          fis = newBufferedReader(new StringReader(input.toString()));
        }
        String str = fis.readLine();
        if (str== null) { //thefile doesn't have anything
          throw newIOException ("Index file for the log of " + taskid+"is empty.");
        }
        String loc =str.substring(str.indexOf(LogFileDetail.LOCATION)+
           LogFileDetail.LOCATION.length());

    从logdir中判断是否有syslog。

    Workaround:

    查询时加入在url上加入filter=SYSLOG就可以看到,不需要修改代码。

  • 相关阅读:
    POJ2407:Relatives(欧拉函数) java程序员
    POJ1664:放苹果(搜索) java程序员
    关于android中数据库的创建以及基础的增删改查的相应操作
    家庭版记账本app开发进度。开发到现在整个app只剩下关于图表的设计了,具体功能如下
    在tap的碎片上与活动进行绑定实现点击事件(日期时间选择以及按钮跳转时间)
    使用tap、Fragment等相关相关知识点。实现类似微信的界面
    android学习相关intent和fragment的先关知识点
    家庭记账本app进度之关于tap的相关操作1
    家庭版记账本app进度之关于listview显示账单,并为其添加点击事件
    家庭版记账本app进度之编辑框组件
  • 原文地址:https://www.cnblogs.com/riskyer/p/3423971.html
Copyright © 2020-2023  润新知