实现hive proxy3-日志目录权限问题解决

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

  使用proxy之后,目录名为proxy之后的用户名目录,但是生成的文件属主是当前登陆用户,导致不能正常写入,日志目录的创建在org.apache.hadoop.hive.ql.history.HiveHistoryImpl类中,
更改后的构造方法(增加了proxy之后的代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public  HiveHistoryImpl(SessionState ss) {
   try  {
     console =  new  LogHelper(LOG);
     if (ss.getConf().getBoolVar(HiveConf.ConfVars.HIVE_USE_CUSTOM_PROXY)){
        LOG.warn( "user custom proxy,gen history log file" );
         proxyUser = ss.getConf().getVar(HiveConf.ConfVars.HIVE_CUSTOM_PROXY_USER);
         if (( "" ).equals(proxyUser)||proxyUser ==  null ||( "hdfs" ).equals(proxyUser)){
             console.printError( "gen history file,use proxy,but proxy user is "  + proxyUser);
             return ;
         }
         conf_file_loc = System.getProperty( "java.io.tmpdir" ) + File.separator + proxyUser;
     } else  {
         conf_file_loc = ss.getConf().getVar(
         HiveConf.ConfVars.HIVEHISTORYFILELOC);
     }
     LOG.warn( "user history log dir is "  + conf_file_loc);
     if  ((conf_file_loc ==  null ) || conf_file_loc.length() ==  0 ) {
       console.printError( "No history file location given" );
       return ;
     }
     // Create directory
     File histDir =  new  File(conf_file_loc);
     if  (!histDir.exists()) {  //目录的创建逻辑
       if  (!histDir.mkdirs()) {
         console.printError( "Unable to create log directory "  + conf_file_loc);
         return ;
       }
     }
     do  {
       histFileName = conf_file_loc + File.separator +  "hive_job_log_"  + ss.getSessionId() +  "_"
         + Math.abs(randGen.nextInt()) +  ".txt" ;
     while  (!  new  File(histFileName).createNewFile());
     console.printInfo( "Hive history file="  + histFileName);
     histStream =  new  PrintWriter(histFileName);
     HashMap<String, String> hm =  new  HashMap<String, String>();
     hm.put(Keys.SESSION_ID.name(), ss.getSessionId());
     log(RecordTypes.SessionStart, hm);
   catch  (IOException e) {
     console.printError( "FAILED: Failed to open Query Log : "  + histFileName
         " "  + e.getMessage(),  "\n"
         + org.apache.hadoop.util.StringUtils.stringifyException(e));
   }
}

日志目录的创建相关代码:

1
2
3
4
5
6
7
8
     // Create directory
     File histDir =  new  File(conf_file_loc);
     if  (!histDir.exists()) {  //目录的创建逻辑
       if  (!histDir.mkdirs()) {
         console.printError( "Unable to create log directory "  + conf_file_loc);
         return ;
       }
     }

一个思路,我们可以把这个目录的权限设大一点,比如777,这里调用了File.mkdirs()方法
(File的mkdirs方法,存在返回false,不存在返回true,创建失败返回false),在File类中最终调用了FileSystem.createDirectory()方法,在File的源码中我们可以看到有如下方法可以设置目录的权限:

1
2
3
4
5
6
7
8
9
10
     public  boolean  setWritable(  boolean  writable,  boolean  ownerOnly) {
         SecurityManager security = System.getSecurityManager();
         if  (security !=  null ) {
             security.checkWrite( path);
         }
         if  (isInvalid()) {
             return  false  ;
         }
         return  fs.setPermission( this , FileSystem ACCESS_WRITE, writable, ownerOnly);
     }

可以通过这个方法来更改日志目录的权限,更改HiveHistoryImpl相关的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private  boolean  createDir;
.....
// Create directory
File histDir =  new  File(conf_file_loc);
if  (!histDir.exists()) {
   if  (!histDir.mkdirs()) {
     console.printError( "Unable to create log directory "  + conf_file_loc);
     return ;
   } else {
     LOG.warn( "create dir success,start chmod,dir is "  + histDir);
     createDir = histDir.setWritable( true , false );
   }
} else {
     LOG.warn( "dir already exists,start chmod,dir is "  + histDir);
     createDir = histDir.setWritable( true , false );
}
do  {
   histFileName = conf_file_loc + File.separator +  "hive_job_log_"  + ss.getSessionId() +  "_"
     + Math.abs(randGen.nextInt()) +  ".txt" ;
while  (!  new  File(histFileName).createNewFile());

不过这里有个限制,因为不能更改别的用户的日志目录权限,因此要求是新建目录(不能更改旧的目录),最好的方法还是日志文件不要用proxy之后的用户文件就可以啦。



本文转自菜菜光 51CTO博客,原文链接:http://blog.51cto.com/caiguangguang/1589891,如需转载请自行联系原作者

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
7月前
|
Dubbo Java 应用服务中间件
Dubbo日志文件输出到指定目录 如何定义?
Dubbo日志文件输出到指定目录 如何定义?
|
Java 测试技术 Docker
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
533 0
|
13天前
|
数据安全/隐私保护
谁动了我的Excel?权限日志告诉你  
多人协同编辑Excel文档时,如何平衡数据共享与安全性是一大挑战。关键在于权限管理,如只读权限、单元格保护等,确保用户在职责范围内编辑,减少误操作风险。复杂场景下,需采用分层权限、实时变更日志和动态权限调整等精细化管理工具,以提高协同效率并保障数据安全。
|
2月前
|
SQL 分布式计算 Hadoop
Hadoop-19 Flume Agent批量采集数据到HDFS集群 监听Hive的日志 操作则把记录写入到HDFS 方便后续分析
Hadoop-19 Flume Agent批量采集数据到HDFS集群 监听Hive的日志 操作则把记录写入到HDFS 方便后续分析
50 2
|
3月前
|
消息中间件 存储 监控
Kafka的logs目录下的文件都是什么日志?
Kafka的logs目录下的文件都是什么日志?
198 11
|
4月前
|
存储 安全 Linux
在Linux中,日志文件通常存储在哪些目录?
在Linux中,日志文件通常存储在哪些目录?
|
4月前
|
Ubuntu Linux 测试技术
在Linux中,已知 apache 服务的访问日志按天记录在服务器本地目录/app/logs 下,由于磁盘空间紧张现在要求只能保留最近7天的访问日志,请问如何解决?
在Linux中,已知 apache 服务的访问日志按天记录在服务器本地目录/app/logs 下,由于磁盘空间紧张现在要求只能保留最近7天的访问日志,请问如何解决?
|
5月前
|
Java Serverless 应用服务中间件
函数计算操作报错合集之JVM启动时找不到指定的日志目录,该如何解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
7月前
|
Dubbo Java 应用服务中间件
Dubbo日志文件输出到指定目录 如何定义?
Dubbo日志文件输出到指定目录 如何定义?
|
7月前
|
Dubbo Java 应用服务中间件
Dubbo日志文件输出到指定目录 如何定义?
Dubbo日志文件输出到指定目录 如何定义?