使用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,如需转载请自行联系原作者