我想提取当前时间戳和 15 分钟前之间的日志,并向配置的人员发送电子邮件。我开发了以下脚本,但它无法正常工作;有人能帮我吗??我有一个包含此模式的日志文件:
[2016-05-24T00:58:04.508-04:00] [oim_server1] [TRACE:32] [] [oracle.iam.scheduler.impl.quartz] [tid: OIMQuartzScheduler_QuartzSchedulerThread] [userId: oiminternal] [ecid: 0000LI6NBsP4yk4LzUS4yW1NBABd000003,1:21904] [APP: oim#11.1.2.0.0] [SRC_CLASS: oracle.iam.scheduler.impl.quartz.QuartzJob] [SRC_METHOD: <init>] Constructor QuartzJob
[2016-05-24T00:58:04.508-04:00] [oim_server1] [TRACE:32] [] [oracle.iam.scheduler.impl.quartz] [tid: OIMQuartzScheduler_QuartzSchedulerThread] [userId: oiminternal] [ecid: 0000LI6NBsP4yk4LzUS4yW1NBABd000003,1:21904] [APP: oim#11.1.2.0.0] [SRC_CLASS: oracle.iam.scheduler.impl.quartz.QuartzJob] [SRC_METHOD: <init>] Constructor QuartzJob
[2016-05-24T00:58:04.513-04:00] [oim_server1] [TRACE:32] [] [oracle.iam.scheduler.impl.quartz] [tid: OIMQuartzScheduler_Worker-1] [userId: oiminternal] [ecid: 0000LI6NBsP4yk4LzUS4yW1NBABd000003,1:21908] [APP: oim#11.1.2.0.0] [SRC_CLASS: oracle.iam.scheduler.impl.quartz.QuartzTriggerListener] [SRC_METHOD: triggerFired] Trigger state 0
[2016-05-24T00:58:04.515-04:00] [oim_server1] [TRACE:32] [] [oracle.iam.scheduler.impl.quartz] [tid: OIMQuartzScheduler_Worker-1] [userId: oiminternal] [ecid: 0000LI6NBsP4yk4LzUS4yW1NBABd000003,1:21908] [APP: oim#11.1.2.0.0] [SRC_CLASS: oracle.iam.scheduler.impl.quartz.QuartzTriggerListener] [SRC_METHOD: triggerFired] Trigger state 0
[2016-05-24T00:58:04.516-04:00] [oim_server1] [TRACE:32] [] [oracle.iam.scheduler.impl.quartz] [tid: OIMQuartzScheduler_Worker-1] [userId: oiminternal] [ecid: 0000LI6NBsP4yk4LzUS4yW1NBABd000003,1:21908] [APP: oim#11.1.2.0.0] [SRC_CLASS: oracle.iam.scheduler.impl.quartz.QuartzTriggerListener] [SRC_METHOD: triggerFired] Trigger Listener QuartzTriggerListener.triggerFired(Trigger trigger, JobExecutionContext ctx)
[2016-05-24T01:00:04.513-04:00] [oim_server1] [WARNING] [] [oracle.iam.scheduler.vo] [tid: OIMQuartzScheduler_Worker-7] [userId: oiminternal] [ecid: 0000LI6NBsP4yk4LzUS4yW1NBABd000003,1:21956] [APP: oim#11.1.2.0.0] IAM-1020021 Unable to execute job : CmyAccess Flat File WD Candidate with Job History Id:1336814[[
org.identityconnectors.framework.common.exceptions.ConfigurationException: Directory does not contain normal files to read HR-76
at org.identityconnectors.flatfile.utils.FlatFileUtil.assertValidFilesinDir(FlatFileUtil.java:230)
at org.identityconnectors.flatfile.utils.FlatFileUtil.getDir(FlatFileUtil.java:176)
at org.identityconnectors.flatfile.utils.FlatFileUtil.getFlatFileDir(FlatFileUtil.java:182)
at org.identityconnectors.flatfile.FlatFileConnector.executeQuery(FlatFileConnector.java:134)
at org.identityconnectors.flatfile.FlatFileConnector.executeQuery(FlatFileConnector.java:58)
at org.identityconnectors.framework.impl.api.local.operations.SearchImpl.rawSearch(SearchImpl.java:105)
at org.identityconnectors.framework.impl.api.local.operations.SearchImpl.search(SearchImpl.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.identityconnectors.framework.impl.api.local.operations.ConnectorAPIOperationRunnerProxy.invoke(ConnectorAPIOperationRunnerProxy.java:93)
at com.sun.proxy.$Proxy735.search(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.identityconnectors.framework.impl.api.local.operations.ThreadClassLoaderManagerProxy.invoke(ThreadClassLoaderManagerProxy.java:107)
at com.sun.proxy.$Proxy735.search(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.identityconnectors.framework.impl.api.BufferedResultsProxy$BufferedResultsHandler.run(BufferedResultsProxy.java:162)
我编写的脚本对发现的错误进行计数并将其存储在带有编号的文件中;如果错误计数增加,它将运行脚本并发送邮件。我可以为此配置 cron,但我编写的脚本无法正常工作。有人可以帮我提取当前时间和过去 15 分钟之间的日志并生成临时文件吗?
LogDir=/data/app/Oracle/Middleware/user_projects/domains/oim_domain/servers/oim_server1/logs
[email protected]
SUBJECT=Failed
MESSAGE="Scheduler failed"
SMTP="SMTPHOSTNAME"
[email protected]
NOW=$(date +"%FT%T.000%-04:00")
T2=$(date --date='15 minutes ago' +"%FT%T.000%-04:00")
OUT=/tmp/oim_server1-diagnostic_$(date +%F-%H-%M).log
find $LogDir -mmin -15 -name "oim_server1-diagnostic.log" > files.txt
count=0;
if [ -f lastCount ]; then
count=$(cat lastCount)
fi
while read file
do
echo "reading file \n " $file
currentCount=$(grep -c 'Directory does not contain normal files to read HR-76' $file)
if [ $currentCount -ne $count -a $currentCount -ne 0 ];then
echo "Error Found " $currentCount
awk -v TSTART="[$T2]" -v TEND="[$NOW]" '$1>=TSTART && $1<=TEND' $LogDir/oim_server1-diagnostic.log > "$OUT"
test -s $OUT &&
echo -e "$MESSAGE" | mailx -S smtp="$SMTP" -a "$OUT" -r "$SENDER" -s "$SUBJECT" "$EMAIL1"
rm -f "$OUT"
fi
echo $currentCount > lastCount
done < files.txt
该脚本正在提取日志,但格式不正确。我找到的最大的日志
(grep -c 'Directory does not contain normal files to read HR-76' $file)
我想提取两个时间戳之间的所有日志。有些行可能没有时间戳,但我也想要这些行。简而言之,我想要属于两个时间戳的每一行。这个脚本给我的日志文件只有时间戳,其余所有行都缺少任何建议???请注意,开始时间戳或结束时间戳可能并不存在于日志的所有行中,但我想要这两个时间戳之间的每一行。上述日志的示例生成:::
[2016-05-24T01:00:04.513-04:00] [oim_server1] [WARNING] [] [oracle.iam.scheduler.vo] [tid: OIMQuartzScheduler_Worker-6] [userId: oiminternal] [ecid: 0000LIt5i3n4yk4LzU^AyW1NEPxf000002,1:23444] [APP: oim#11.1.2.0.0] IAM-1020021 Unable to execute job : CmyAccess Flat File WD Employee with Job History Id:46608[[
答案1
我会用:
awk -v limit="$(date -d '15 minutes ago' +'[%FT%T')" '
$0 >= limit' < log-file
这忽略了当 GMT 偏移量从 -04:00 到 -05:00 并返回(如果您的时区适用夏令时)时,您每年可能会遇到两个小时的潜在问题。
date -d
是 GNU 特定的,但您已经在使用它了。
答案2
你几乎已经拥有了。
步骤1
在 GNU 和 Linux 以及其他系统上,该date
命令可用于在给定用户友好的时间表达式的情况下打印出时间规范的任意格式。例如,我可以使用以下命令获取表示过去 15 分钟的时间的字符串:
date --date='15 minutes ago'
您几乎已经用代码完成了此操作,尽管效率较低。但你忽略了微秒。想必您实际上并不关心它们,但您确实必须匹配它们。时区可以用 '%:z' 来完成,但大概你需要匹配现有的时区;夏令时切换后不久,事情可能会发生故障。如果您必须担心多个时区,则需要正则表达式或 Sobrique 的解决方案。买者自负,你可能会逃脱:
NOW=$(date +"%FT%T.000%-04:00")
T2=$(date --date='15 minutes ago' +"%FT%T.000%-04:00")
第2步
您可以使用 NOW 和 T2 作为 的输入awk
。基于字符串的匹配在这里可以很好地工作,但是 awk 可以让您通过执行大于和小于字符串比较来确保每行都符合所需的时间范围。
awk -v TSTART="[$T2]" -v TEND="[$NOW]" '$1>=TSTART && $1<=TEND'
步骤 3(新)
您必须在带时间戳的行之间获取未加时间戳的日志行。因此,我们使用上面的 awk 代码来匹配时间戳行,当时间戳在正确的范围内时,设置一个标志。仅当该标志设置为 1 时,才会打印当前行。
awk -v TSTART="[$T2]" -v TEND="[$NOW]" \
'/^\[[^ ]*\] / { log = ($1>=TSTART && $1<=TEND) } log { print }'
步骤4
像往常一样,重定向输出,但您应该注意,如果您每 15 分钟运行一次脚本,则当前的重定向代码将覆盖同一文件,因为 %H 在至少 3 次运行中不会发生更改。最好把它写成%H-%M之类的。但根本不需要任何重定向到文件。您可以直接将其发送到邮件(除非您确实需要附件):
{
echo "$MESSAGE"; echo
awk -v TSTART="[$T2]" -v TEND="[$NOW]" '$1>=TSTART && $1<=TEND' $LogDir/oim_server1-diagnostic.log
} | mailx -S smtp="$SMTP" -r "$SENDER" -s "$SUBJECT" "$EMAIL1"
脚本的其余部分应该按原样工作。
但是,在上述设置中,现在您无法获得可以使用相关日期时间戳轻松保存的附件。如果没有输出,也许您不想发送邮件。所以你可以这样做:
OUT=/tmp/oim_server1-diagnostic_$(date +%F-%H-%M)
awk -v TSTART="[$T2]" -v TEND="[$NOW]" '$1>=TSTART && $1<=TEND' $LogDir/oim_server1-diagnostic.log > "$OUT"
test -s $OUT &&
echo -e "$MESSAGE" | mailx -S smtp="$SMTP" -a "$OUT" -r "$SENDER" -s "$SUBJECT" "$EMAIL1"
rm -f "$OUT"
这会自行清理,因此您不会留下大量诊断日志文件。
答案3
正则表达式不是匹配时间戳的好选择,因为它们并不真正“理解”数值。因此,我建议解析时间戳:
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $now = time();
my $last = $now - 15 * 60;
while ( <> ) {
my ( $timecode ) = m/\[([^\.]+)/;
print $timecode;
my $t = Time::Piece -> strptime ( $timecode, '%Y-%m-%dT%H:%M:%S' );
print if $t > $last;
}
这可以简单地表示为:
perl -MTime::Piece -ne 'print if Time::Piece -> strptime ( m/\[([^\.]+)/, '%Y-%m-%dT%H:%M:%S' ) > time() - 15 * 60'
答案4
尝试这个命令,它对我有用
sed -n "/$(date --date="15 minutes ago" +%T)/,/$(date +%T)/p" logfile > newfile
date --date="15 minutes ago" "+%T"
是15分钟之前的时间
date "+%T"
是当前时间
例如:正如我上面所说,“+%T”
将以(%H:%M:%S)的格式表示系统时间。如果我们运行此命令,它将获取当前运行时间戳 1:15:101:15:10
之前 15 分钟的日志。1:01:10