Lazarus 日志工具 MultiLog

Posted hieroly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lazarus 日志工具 MultiLog相关的知识,希望对你有一定的参考价值。

MultiLog是一种同时以灵活性和低开销为目标的日志系统。顾名思义,它可用于将日志实例到多个目标,如文本文件、可视控件或其他应用程序。添加新的日志目标使用两个方法就可以实现了,其中一个方法是可选的。
MultiLog通常类似于CodeSite、Smart Inect、Overseer和EstLogger,但它没有紧跟其中的任何一个,以不同的方式实现了许多功能,甚至具有一些独特的功能。

技术图片

目前(2019年5月)版本是v 0.6.0.0。

MultiLog的使用是极其简单的,如前面说的,仅仅两步就可以实现日志记录:

1:构建通道

2:输出

通道可以是 IPCChannel,FileChannel,或可视控件,MultiLog预制了三个功能,直接使用即可,IPCChannel实现进程间辅助监视,利用例程View项目,即可实现跨进程Log监视

技术图片

直接在中应用 MultiLog 单元,其定义了Logger全局实例。

技术图片

如果要输出到某文件比如日期型号日志 “20190520.log”,

vLOGFileNameM  := FormatDateTime(yyyymmdd, Now);
vlogName       := vLOGFileNameM + .log;
FFileChannel   := TFileChannel.Create(vlogName);
FFileLogHaneld := Logger.Channels.Add(FFileChannel);

这里对FileChannel做了点点调整,加入了固定的目录“Logs”。

constructor TFileChannel.Create(const AFileName: string; ChannelOptions: TFileChannelOptions);
const
  logDir = Logs;
begin
  if not DirectoryExists(logDir) then
    ForceDirectories(logDir);
  FShowPrefix := fcoShowPrefix in ChannelOptions;
  FShowTime   := fcoShowTime in ChannelOptions;
  FShowHeader := fcoShowHeader in ChannelOptions;
  Active      := True;
  FFileName   := logDir + DirectorySeparator + AFileName;
end;

FileChannel.Create 还带一个ChannelOptions 参数,是个集合 ,默认是带[fcoShowHeader, fcoShowTime],如果要显示如故障、提示、警告需要加上fcoShowPrefix。

with Logger do
  begin
    Channels.Add(LogTreeView1.Channel);
    Channels.Add(TIPCChannel.Create());
    Channels.Add(TFileChannel.Create(debug.log,[fcoShowHeader, fcoShowPrefix, fcoShowTime]));
    DefaultClasses := [lcDebug];
  end;

这也是MultiLog带了一个综合例子,Logger对Send做了多种overload,那么可以对Pascal语言的所有类型直接输出,包括TStringList,“状态”计数,SendError(’’)或者Send([lcError],’’),记录调用情况。

技术图片

procedure TForm1.TestLogClick(Sender: TObject);
var
  AList:TStringList;
begin
  with Logger do
  begin
    ActiveClasses:=lcAll;
    EnterMethod(Sender,TestLogClick);
    AList:=TStringList.Create;
    with AList do
    begin
      Add(aaaaaaa);
      Add(bbbbbbb);
      Add(ccccccc);
    end;
    Send(A Text Message);
    Send(Another Text Message);
    Send(A StringList, AList);
    AList.Destroy;
    SendError(A Error Message);
    SubLogClick(butSubLog);
    DefaultClasses := [lcWarning];
    ActiveClasses:=[lcDebug,lcInfo];
    Send(This Text Should NOT be logged);
    Send([lcDebug],This Text Should be logged);
    ActiveClasses:=[];
    Send([lcWarning],But This Text Should NOT);
    //Exitmethod is called even if not active if there‘s a unpaired EnterMethod
    ExitMethod(Sender,TestLogClick);
    ActiveClasses:=lcAll;
  end;
end;

procedure TForm1.SubLogClick(Sender: TObject);
 var
   OldClasses: set of TDebugClass;
 begin
   with Logger do
   begin
     OldClasses:=ActiveClasses;
     ActiveClasses:=lcAll;
     EnterMethod(Sender,SubLogClick);
     SendIf(Only show if called by TestLogClick,CalledBy(TestLogClick));
     Send(AText inside DoIt);
     SendWarning(AWarning);
     SendCallStack(CallStack example);
     Send(A String,sadjfgadsfbmsandfb);
     Send(AInteger,4957);
     Send(A Boolean,True);
     ExitMethod(Sender,SubLogClick);
     ActiveClasses:=OldClasses;
   end;
 end;


=== Log Session Started at 2019/5/12 9:19:41 by MultiLogDemo ===
09:19:45.201 >>ENTER METHOD: TButton(butTestLog).TestLogClick
09:19:45.205   INFO: A Text Message
09:19:45.209   INFO: Another Text Message
09:19:45.212   STRINGS: A StringList
                 aaaaaaa
                 bbbbbbb
                 ccccccc
09:19:45.215   ERROR: A Error Message
09:19:45.218   >>ENTER METHOD: TButton(butSubLog).SubLogClick
09:19:45.221     CONDITIONAL: Only show if called by TestLogClick
09:19:45.224     INFO: AText inside DoIt
09:19:45.227     WARNING: AWarning
09:19:45.336     CALL STACK: CallStack example
                     $000000010002DF2D line 329 of unit1.pas
                     $000000010002CF0F line 144 of unit1.pas
                     $0000000100126EF8 line 2913 of include/control.inc
                     $00000001001448FA line 55 of include/buttoncontrol.inc
                     $000000010014502F line 169 of include/buttons.inc
                     $00000001001447C2 line 21 of include/buttoncontrol.inc
                     $000000010000E1B5
                     $0000000100119B3C line 5419 of include/wincontrol.inc
                     $00000001001A9277 line 112 of lclmessageglue.pas
                     $00000001000FBEE8 line 2515 of win32/win32callback.inc
                     $00000001000FC6BC line 2677 of win32/win32callback.inc
                     $00000001001AEAFF line 105 of win32/win32pagecontrol.inc
                     $00007FFE5F37CA66
                     $0000000000090B9C
09:19:45.342     VALUE: A String = sadjfgadsfbmsandfb
09:19:45.346     VALUE: AInteger = 4957
09:19:45.349     VALUE: A Boolean = True
09:19:45.352   <<EXIT METHOD: TButton(butSubLog).SubLogClick
09:19:45.354   INFO: This Text Should be logged
09:19:45.356 <<EXIT METHOD: TButton(butTestLog).TestLogClick

通过监视进程MultiLog View监视到的数据,示例Log的输出。

技术图片

是不是很方便!

以上是关于Lazarus 日志工具 MultiLog的主要内容,如果未能解决你的问题,请参考以下文章

Windows 逆向CheatEngine 工具 ( CheatEngine 简介 | 使用 Lazarus 编译 CE 源码 | CheatEngine 相关文档资料 )

用 Lazarus 开发 OPC Client 2 (关于Lazarus 编译器)

FreePascal - CodeTyphon 和 Lazarus, 如何像Delphi一样有代码之间的连线?

Lazarus - SelectFirst 给出错误

argparse 代码片段只打印部分日志

常用python日期日志获取内容循环的代码片段