「javashell日志」java的日志

博主:adminadmin 2023-01-03 09:39:06 1114

本篇文章给大家谈谈javashell日志,以及java的日志对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

怎么通过java去调用并执行shell脚本以及问题总结

对于第一个问题:java抓取,并且把结果打包。那么比较直接的做法就是,java接收各种消息(db,metaq等等),然后借助于jstorm集群进行调度和抓取。

最后把抓取的结果保存到一个文件中,并且通过调用shell打包, 回传。 也许有同学会问,

为什么不直接把java调用odps直接保存文件,答案是,我们的集群不是hz集群,直接上传odps速度很有问题,因此先打包比较合适。(这里不纠结设计了,我们回到正题)

java调用shell的方法

通过ProcessBuilder进行调度

这种方法比较直观,而且参数的设置也比较方便, 比如我在实践中的代码(我隐藏了部分业务代码):

ProcessBuilderpb = new ProcessBuilder("./" + RUNNING_SHELL_FILE, param1,

param2, param3);

pb.directory(new File(SHELL_FILE_DIR));

int runningStatus = 0;

String s = null;

try {

Process p = pb.start();

try {

runningStatus = p.waitFor();

} catch (InterruptedException e) {

}

} catch (IOException e) {

}

if (runningStatus != 0) {

}

return;

这里有必要解释一下几个参数:

RUNNING_SHELL_FILE:要运行的脚本

SHELL_FILE_DIR:要运行的脚本所在的目录; 当然你也可以把要运行的脚本写成全路径。

runningStatus:运行状态,0标识正常。 详细可以看java文档。

param1, param2, param3:可以在RUNNING_SHELL_FILE脚本中直接通过1,2,$3分别拿到的参数。

直接通过系统Runtime执行shell

这个方法比较暴力,也比较常用, 代码如下:

p = Runtime.getRuntime().exec(SHELL_FILE_DIR + RUNNING_SHELL_FILE + " "+param1+" "+param2+" "+param3);

p.waitFor();

我们发现,通过Runtime的方式并没有builder那么方便,特别是参数方面,必须自己加空格分开,因为exec会把整个字符串作为shell运行。

可能存在的问题以及解决方法

如果你觉得通过上面就能满足你的需求,那么可能是要碰壁了。你会遇到以下情况。

没权限运行

这个情况我们团队的朱东方就遇到了, 在做DTS迁移的过程中,要执行包里面的shell脚本, 解压出来了之后,发现执行不了。 那么就按照上面的方法授权吧

java进行一直等待shell返回

这个问题估计更加经常遇到。 原因是, shell脚本中有echo或者print输出, 导致缓冲区被用完了! 为了避免这种情况, 一定要把缓冲区读一下, 好处就是,可以对shell的具体运行状态进行log出来。 比如上面我的例子中我会变成:

ProcessBuilderpb = new ProcessBuilder("./" + RUNNING_SHELL_FILE, keyword.trim(),

taskId.toString(), fileName);

pb.directory(new File(CASPERJS_FILE_DIR));

int runningStatus = 0;

String s = null;

try {

Process p = pb.start();

BufferedReaderstdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));

BufferedReaderstdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

while ((s = stdInput.readLine()) != null) {

LOG.error(s);

}

while ((s = stdError.readLine()) != null) {

LOG.error(s);

}

try {

runningStatus = p.waitFor();

} catch (InterruptedException e) {

}

记得在start()之后, waitFor()之前把缓冲区读出来打log, 就可以看到你的shell为什么会没有按照预期运行。 这个还有一个好处是,可以读shell里面输出的结果, 方便java代码进一步操作。

也许你还会遇到这个问题,明明手工可以运行的命令,java调用的shell中某一些命令居然不能执行,报错:命令不存在!

比如我在使用casperjs的时候,手工去执行shell明明是可以执行的,但是java调用的时候,发现总是出错。

通过读取缓冲区就能发现错误日志了。 我发现即便自己把安装的casperjs的bin已经加入了path中(/etc/profile,

各种bashrc中)还不够。 比如:

exportNODE_HOME="/home/admin/node"

exportCASPERJS_HOME="/home/admin/casperjs"

exportPHANTOMJS_HOME="/home/admin/phantomjs"

exportPATH=$PATH:$JAVA_HOME/bin:/root/bin:$NODE_HOME/bin:$CASPERJS_HOME/bin:$PHANTOMJS_HOME/bin

原来是因为java在调用shell的时候,默认用的是系统的/bin/下的指令。特别是你用root权限运行的时候。 这时候,你要在/bin下加软链了。针对我上面的例子,就要在/bin下加软链:

ln -s /home/admin/casperjs/bin/casperjscasperjs;

ln -s /home/admin/node/bin/nodenode;

ln -s /home/admin/phantomjs/bin/phantomjsphantomjs;

这样,问题就可以解决了。

如果是通过java调用shell进行打包,那么要注意路径的问题了

因为shell里面tar的压缩和解压可不能直接写:

tar -zcf /home/admin/data/result.tar.gz /home/admin/data/result

直接给你报错,因为tar的压缩源必须到路径下面, 因此可以写成

tar -zcf /home/admin/data/result.tar.gz -C /home/admin/data/ result

如果我的shell是在jar包中怎么办?

答案是:解压出来。再按照上面指示进行操作。(1)找到路径

String jarPath = findClassJarPath(ClassLoaderUtil.class);

JarFiletopLevelJarFile = null;

try {

topLevelJarFile = new JarFile(jarPath);

EnumerationJarEntry entries = topLevelJarFile.entries();

while (entries.hasMoreElements()) {

JarEntryentry = entries.nextElement();

if (!entry.isDirectory() entry.getName().endsWith(".sh")) {

对你的shell文件进行处理

}

}

对文件处理的方法就简单了,直接touch一个临时文件,然后把数据流写入,代码:

FileUtils.touch(tempjline);

tempjline.deleteOnExit();

FileOutputStreamfos = new FileOutputStream(tempjline);

IOUtils.copy(ClassLoaderUtil.class.getResourceAsStream(r), fos);

fos.close();

如何用shell统计日志文件里每一小时内的数

用spark-shell去进行日志信息的统计的话,首先第一步就是创建rdd,将数据加载进去。

第二步,就是进行map操作,然后调用filter进行过滤,包含404的页面,然后调用count进行统计行数。

当然,如果你要进行更详细的统计,或者操作(如果你的log,每列数量都相同的话),可以使用java编写自定义的日志处理类,然后在map的时候,对log进行操作。

如何使用Java程序或shell脚本删除某目录下超过一周的日志文件,如删除server.log.2015-06-15文件

如果java需要控制台的数据会比较麻烦

不过java里面最好不要输出东西,否则屏幕会乱,不看的话可以类似:

java your-program 1/dev/null 2/dev/null

或者

java your-program 1out.log 2err.log

请教个java调用shell命令操作

近日项目中有这样一个需求:系统中的外币资金调度完成以后,要将调度信息生成一个Txt文件,然后将这个Txt文件发送到另外一个系统(Kondor)中。生成文件自然使用OutputStreamWirter了,发送文件有两种方式,一种是用写个一个类似于FTP功能的程序,另外一种就是使用Java来调用Shell,在Shell中完成文件的发送操作。我们选择后一种,即当完成外币资金的调度工作后,用Java的OutputStreamWriter来生成一个Txt文件,然后用Java来调用Shell脚本,在Shell脚本中完成FTP文件到Kondor系统的工作。

以下为Java程序JavaShellUtil.java:import java.io.BufferedReader;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

public class JavaShellUtil {

//基本路径

private static final String basePath = "/tmp/";

//记录Shell执行状况的日志文件的位置(绝对路径)

private static final String executeShellLogFile = basePath + "executeShell.log";

//发送文件到Kondor系统的Shell的文件名(绝对路径)

private static final String sendKondorShellName = basePath + "sendKondorFile.sh";

public int executeShell(String shellCommand) throws IOException {

int success = 0;

StringBuffer stringBuffer = new StringBuffer();

BufferedReader bufferedReader = null;

//格式化日期时间,记录日志时使用

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:SS ");

try {

stringBuffer.append(dateFormat.format(new Date())).append("准备执行Shell命令 ").append(shellCommand).append(" \r\n");

Process pid = null;

String[] cmd = {"/bin/sh", "-c", shellCommand};

//执行Shell命令

pid = Runtime.getRuntime().exec(cmd);

if (pid != null) {

stringBuffer.append("进程号:").append(pid.toString()).append("\r\n");

//bufferedReader用于读取Shell的输出内容 bufferedReader = new BufferedReader(new InputStreamReader(pid.getInputStream()), 1024);

pid.waitFor();

} else {

stringBuffer.append("没有pid\r\n");

}

stringBuffer.append(dateFormat.format(new Date())).append("Shell命令执行完毕\r\n执行结果为:\r\n");

String line = null;

//读取Shell的输出内容,并添加到stringBuffer中

while (bufferedReader != null

(line = bufferedReader.readLine()) != null) {

stringBuffer.append(line).append("\r\n");

}

} catch (Exception ioe) {

stringBuffer.append("执行Shell命令时发生异常:\r\n").append(ioe.getMessage()).append("\r\n");

} finally {

if (bufferedReader != null) {

OutputStreamWriter outputStreamWriter = null;

try {

bufferedReader.close();

//将Shell的执行情况输出到日志文件中

OutputStream outputStream = new FileOutputStream(executeShellLogFile);

outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");

outputStreamWriter.write(stringBuffer.toString());

} catch (Exception e) {

e.printStackTrace();

} finally {

outputStreamWriter.close();

}

}

success = 1;

}

return success;

}

}

以下是Shell脚本sendKondorFile.sh,该Shell脚本的作用是FTP文件到指定的位置:

#!/bin/sh

#日志文件的位置

logFile="/opt/fms2_kondor/sendKondorFile.log"

#Kondor系统的IP地址,会将生成的文件发送到这个地址

kondor_ip=192.168.1.200

#FTP用户名

ftp_username=kondor

#FTP密码

ftp_password=kondor

#要发送的文件的绝对路径

filePath=""

#要发送的文件的文件名

fileName=""

#如果Shell命令带有参数,则将第一个参数赋给filePath,将第二个参数赋给fileName

if [ $# -ge "1" ]

then

filePath=$1

else

echo "没有文件路径"

echo "没有文件路径\n"

$logFile

return

fi

if [ $# -ge "2" ]

then

fileName=$2

else

echo "没有文件名"

echo "没有文件名\n"

$logFile

return

fi

echo "要发送的文件是 ${filePath}/${fileName}"

cd ${filePath}

ls $fileName

if (test $? -eq 0)

then

echo "准备发送文件:${filePath}/${fileName}"

else

echo "文件 ${filePath}/${fileName} 不存在"

echo "文件 ${filePath}/${fileName} 不存在\n"

$logFile

return

fi

ftp -n ${kondor_ip}

_end

user ${ftp_username} ${ftp_password}

asc

prompt

put $fileName

bye

_end

echo "`date +%Y-%m-%d' '%H:%M:%S` 发送了文件 ${filePath}/${fileName}"

echo "`date +%Y-%m-%d' '%H:%M:%S` 发送了文件 ${filePath}/${fileName}\n"

$logFile

调用方法为:

JavaShellUtil javaShellUtil = new JavaShellUtil();

//参数为要执行的Shell命令,即通过调用Shell脚本sendKondorFile.sh将/temp目录下的tmp.pdf文件发送到192.168.1.200上

int success = javaShellUtil.executeShell("sh /tmp/sendKondorFile.sh /temp tmp.pdf");

javashell日志的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java的日志、javashell日志的信息别忘了在本站进行查找喔。