• 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就可以看到,不需要修改代码。

  • 相关阅读:
    worldWind发布1.3.2版本了
    XMLSerializer中数组对象的设定
    IE6+UTF8的一个怪异问题
    恢复ServU管理员密码方法
    asp.net中的窗体身份验证(不同的角色访问不同的目录)
    什么是 Landing Page?
    如何让排名更加稳定
    JS替换空格回车换行符
    外部调用ZBLOG文章的方法
    表单填写字母时大小写自动互转(CSS方式)
  • 原文地址:https://www.cnblogs.com/riskyer/p/3423971.html
Copyright © 2020-2023  润新知