在perl中编写子例程到日志文件

问题描述 投票:0回答:3

我是 Perl 脚本新手。我想将子程序测试写入日志文件。 例如

my ($logfile, $logpath);
$logpath = '/usr/bin';
$logfile = "$logpath/log.txt"; 
open (LOG,">>","$logfile") || die ("Error : can't open log file");

sub test
{
   print "Hi\n"; 
   my $date = `date`;
}

sub logFunc
{
   print LOG "Writing log files\n";
   print LOG test(); # we cannot do like this :)
}

logFunc();

假设它们有 15 个以上的子例程。因此,要将每个子例程中的命令写入日志文件,我必须编写 print LOG "[Command] "; 工作正常,但脚本长度很大。那么使用通用子例程是他们实现这一目标的方法吗?

perl
3个回答
4
投票

您的代码存在几个问题。

  1. 您确定拥有(并且想要)对

    /usr/bin/
    的写入权限吗?

  2. 您永远不会调用您的

    log()
    test()
    子例程。没有人会自动呼叫他们中的任何一个。

  3. 名称

    log
    与内置
    log
    函数冲突。因此,您要么必须使用前缀与符号
    &log()
    (这很丑陋)来调用它,要么重命名它。

  4. 您的

    test()
    子仅具有隐式返回值。而是明确返回
    $date
    的值。

  5. 您正在使用已弃用的 2 参数版本的

    open
    ,使用裸字全局文件句柄。请使用带有词法文件句柄的 3-arg 版本:
    open my $log_fh, '>>', $logfile


3
投票

一些提示:

  • 始终在脚本顶部添加
    use strict;
    use warnings;
  • 由于您正在处理读写文件,因此还应该添加
    use autodie;
    。如果您无法打开文件或无法写入打开的文件,这将自动终止您的程序。
  • 当 Perl 无需调用操作系统命令就可以完全执行您想要的操作时,请不要使用操作系统命令。
  • 子例程通常接受参数并返回某种类型的值。在您的情况下,让您的
    test
    子例程返回一些内容以写入日志。或者,仅创建一个写入日志的日志子例程,并让您的测试子例程调用它。

我在这里反转你的子程序调用。我创建了一个

write_to_log
子例程来处理我的子例程调用。我的
write_to_log
添加日期/时间戳并写入该日期/时间戳和我的消息。我的各种子程序现在只需为我调用
write_to_log

注意我的所有子例程都返回某种值。

say
命令(以及
print
)在成功时返回非零值,在失败时返回
0
。我可以用它来测试我对子例程的调用是否有效。

use strict;
use warnings;
use autodie;
use features qw(say);   #Allows you to use `say` instead of `print:

my $log_file = "/usr/bin/log.txt";    #You have write permission to this directory?

open my $log_fh, ">", $log_file;

my test ( $log_fh ) or die qq(Can't write to the log);   #Pass the file handle to log
my test2 ( $log_fh ) or die qq(Can't write to the log);

close $log_fh;

sub test {
    return write_to_log ( $log_fh, "Hello World!" );
}
sub test2 {
    return write_to_log ( $log_fh, "Goodbye World!" );
}

sub write_to_log {
    my $file_handle  = shift;
    my $message      = shift;

    use Time::Piece;

    my $time = localtime->cdate;
    return say {$file_handle} "$time: $message";
}

这里有一个网页,其中列出了学习现代 Perl 的好书以及在这些书中要查找的内容。如果您开始学习 Perl,请使用其中一本书籍。


0
投票

现在是 2024 年,PERL 主要由像我这样偶尔需要查看一些遗留代码的人使用。通常我们没有时间、耐心或权限来安装模块。一个仅使用基本 Perl 命令的简单函数:

#Print based on loglevel 
sub log {
    my %LOG_LEVELS=( "ERROR"=>0, "WARNING" =>1 , "INFO"=> 2, "DEBUG"=> 3);
    printf("[$_[0]] $_[1]\n") if $LOG_LEVELS{uc($loglevel)}+0 >= $LOG_LEVELS{uc($_[0])}+0;
}

并调用这个函数

&log("INFO", "Calling script to generate result");
$result=`blahblah`;
if (index($result,"OK") == -1) {
    &log("ERROR", "Generate role FAILED with status $result");
}
else
{
    &log("DEBUG", "Sucessfully created ".$result);
}

它不能处理所有情况,但您可以轻松地在 LOG_LEVELS 数组中添加具有更高/更低数字的更多级别。

© www.soinside.com 2019 - 2024. All rights reserved.