• 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.index找location看是否有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,

     

     	private boolean haveTaskLog(TaskAttemptID taskId, boolean isCleanup,
    			TaskLog.LogName type) throws IOException {
    		File f = TaskLog.getTaskLogFile(taskId, isCleanup, type);
    		if (f.exists() && f.canRead()) {
    			return true;
    		} else {
    			File indexFile = TaskLog.getIndexFile(taskId, isCleanup);
    			if (!indexFile.exists()) {
    				return false;
    			}
    
    
    			BufferedReader fis;
    			try {
    				fis = new BufferedReader(new InputStreamReader(
    						SecureIOUtils.openForRead(indexFile,
    								TaskLog.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 = new StringBuffer();
    				input.append(LogFileDetail.LOCATION
    						+ TaskLog.getAttemptDir(taskId, isCleanup) + "
    ");
    				for (LogName logName : TaskLog.LOGS_TRACKED_BY_INDEX_FILES) {
    					input.append(logName + ":0 -1
    ");
    				}
    				fis = new BufferedReader(new StringReader(input.toString()));
    			}
    
    
    			try {
    				String str = fis.readLine();
    				if (str == null) { // thefile doesn't have anything
    					throw new IOException("Index file for the log of " + taskId
    							+ "is empty.");
    				}
    				String loc = str.substring(str.indexOf(LogFileDetail.LOCATION)
    						+ LogFileDetail.LOCATION.length());
    				File tf = new File(loc, type.toString());
    				return tf.exists() && tf.canRead();
    
    
    			} finally {
    				if (fis != null)
    					fis.close();
    			}
    		}
    
    
    	}
    

    从logdir中判断是否有syslog。

    Workaround:

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

  • 相关阅读:
    【特效】导航下拉菜单(二级三级都有)
    【特效】移入显示移出隐藏
    【特效】jquery选项卡插件,页面多个选项卡统一调用
    使用MR求解多个矩阵的乘积之后
    由SequenceFile.Writer(key,value)谈toString()方法
    自定义数据类型写入SequenceFile并读出
    hadoop中URI理解
    输入格式CombineFileInput
    分布式缓存DistributedCache的使用
    输入格式MultipleInput
  • 原文地址:https://www.cnblogs.com/yangjun1120/p/3424610.html
Copyright © 2020-2023  润新知