1 Star 1 Fork 1

大量/QuickCore

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
Quick.Core.Logging.pas 37.42 KB
一键复制 编辑 原始数据 按行查看 历史
Exilon 提交于 2023-03-18 06:57 +08:00 . [logging] Added elasticsearch provider
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
{ ***************************************************************************
Copyright (c) 2016-2023 Kike Prez
Unit : Quick.Core.Logging
Description : Core Logging
Author : Kike Prez
Version : 1.8
Created : 02/11/2019
Modified : 01/03/2023
This file is part of QuickCore: https://github.com/exilon/QuickCore
***************************************************************************
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*************************************************************************** }
unit Quick.Core.Logging;
{$i QuickCore.inc}
interface
uses
{$IFDEF DEBUG_LOGGING}
Quick.Debug.Utils,
{$ENDIF}
System.SysUtils,
Quick.Commons,
Quick.Options,
Quick.Options.Serializer.Json,
Quick.Options.Serializer.Yaml,
Quick.AutoMapper,
Quick.Core.Logging.Abstractions,
Quick.Logger,
{$IFDEF ANDROID}
System.IOUtils,
{$ELSE}
Quick.Console,
Quick.Logger.Provider.Console,
{$ENDIF}
Quick.Logger.Provider.Files,
Quick.Logger.Provider.Redis,
Quick.Logger.Provider.Rest,
{$IFDEF MSWINDOWS}
Quick.Logger.Provider.EventLog,
Quick.Logger.Provider.ADODB,
{$ENDIF}
Quick.Logger.Provider.Telegram,
Quick.Logger.Provider.Slack,
Quick.Logger.Provider.Email,
Quick.Logger.Provider.SysLog,
Quick.Logger.Provider.ElasticSearch,
{$IFDEF DEBUG}
{$IFDEF DEBUG_HANDLEDEXCEPTIONS}
Quick.Logger.ExceptionHook,
{$ENDIF}
{$ENDIF}
Quick.Logger.UnhandledExceptionHook;
type
TQuickLogger = class(TInterfacedObject,ILogger)
private
fLogger : TLogger;
public
constructor Create;
destructor Destroy; override;
function Providers : TLogProviderList;
procedure Init;
procedure Info(const aMsg : string); overload;
procedure Info(const aMsg : string; aValues : array of const); overload;
procedure Succ(const aMsg : string); overload;
procedure Succ(const aMsg : string; aParams : array of const); overload;
procedure Done(const aMsg : string); overload;
procedure Done(const aMsg : string; aValues : array of const); overload;
procedure Warn(const aMsg : string); overload;
procedure Warn(const aMsg : string; aValues : array of const); overload;
procedure Error(const aMsg : string); overload;
procedure Error(const aMsg : string; aValues : array of const); overload;
procedure Critical(const aMsg : string); overload;
procedure Critical(const aMsg : string; aValues : array of const); overload;
procedure Trace(const aMsg : string); overload;
procedure Trace(const aMsg : string; aValues : array of const); overload;
procedure Debug(const aMsg : string); overload;
procedure Debug(const aMsg : string; aValues : array of const); overload;
procedure &Except(const aMsg : string; aValues : array of const); overload;
procedure &Except(const aMsg, aException, aStackTrace : string); overload;
procedure &Except(const aMsg : string; aValues: array of const; const aException, aStackTrace: string); overload;
end;
TSendLimitTimeRange = Quick.Logger.TSendLimitTimeRange;
{$M+}
TLogSendLimit = class
private
fTimeRange : TSendLimitTimeRange;
fLimitEventTypes : TLogLevel;
fMaxSent: Integer;
published
property TimeRange : TSendLimitTimeRange read fTimeRange write fTimeRange;
property LimitEventTypes : TLogLevel read fLimitEventTypes write fLimitEventTypes;
property MaxSent : Integer read fMaxSent write fMaxSent;
end;
{$M-}
{$M+}
TJsonOutputOptions = class
private
fUseUTCTime : Boolean;
fTimeStampName : string;
published
property UseUTCTime : Boolean read fUseUTCTime write fUseUTCTime;
property TimeStampName : string read fTimeStampName write fTimeStampName;
end;
{$M-}
TEventType = Quick.Logger.TEventType;
TLogLevel = Quick.Logger.TLogLevel;
TLoggerOptions = class(TOptions)
private
fFormatSettings : TFormatSettings;
fTimePrecission : Boolean;
fMaxFailsToRestart : Integer;
fMaxFailsToStop : Integer;
fUsesQueue : Boolean;
fEnvironment : string;
fPlatformInfo : string;
fSendLimits : TLogSendLimit;
fLogLevel : TLogLevel;
fIncludedInfo : TIncludedLogInfo;
fEventTypeNames : TEventTypeNames;
fCustomMsgOutput : Boolean;
fEnabled : Boolean;
fAppName: string;
protected
fOutputAsJson : Boolean;
fJsonOutputOptions : TJsonOutputOptions;
public
constructor Create; override;
destructor Destroy; override;
published
property MaxFailsToRestart : Integer read fMaxFailsToRestart write fMaxFailsToRestart;
property MaxFailsToStop : Integer read fMaxFailsToStop write fMaxFailsToStop;
property AppName : string read fAppName write fAppName;
property Environment : string read fEnvironment write fEnvironment;
property IncludedInfo : TIncludedLogInfo read fIncludedInfo write fIncludedInfo;
property SendLimits : TLogSendLimit read fSendLimits write fSendLimits;
property LogLevel : TLogLevel read fLogLevel write fLogLevel;
property CustomMsgOutput : Boolean read fCustomMsgOutput write fCustomMsgOutput;
property Enabled : Boolean read fEnabled write fEnabled;
end;
TLoggerOptionsProc<T : TLoggerOptions> = reference to procedure(aOptions : T);
TConsoleLoggerOptions = class(TLoggerOptions)
private
fShowEventColors : Boolean;
fShowTimeStamp : Boolean;
//fEventTypeColors : TEventTypeColors;
fShowEventTypes : Boolean;
fUnderlineHeaderEventType : Boolean;
published
property ShowEventColors : Boolean read fShowEventColors write fShowEventColors;
property ShowTimeStamp : Boolean read fShowTimeStamp write fShowTimeStamp;
property ShowEventType : Boolean read fShowEventTypes write fShowEventTypes;
property UnderlineHeaderEventType : Boolean read fUnderlineHeaderEventType write fUnderlineHeaderEventType;
//property EventTypeColor[cEventType : TEventType] : TConsoleColor read GetEventTypeColor write SetEventTypeColor;
end;
TFileLoggerOptions = class(TLoggerOptions)
private
fFileName : string;
fMaxRotateFiles : Integer;
fMaxFileSizeInMB : Integer;
fDailyRotate : Boolean;
fCompressRotatedFiles : Boolean;
fRotatedFilesPath : string;
fShowEventTypes : Boolean;
fShowHeaderInfo : Boolean;
fUnderlineHeaderEventType: Boolean;
fAutoFlush : Boolean;
fAutoFileName : Boolean;
published
property FileName : string read fFileName write fFileName;
{$IFDEF MSWINDOWS}
property AutoFileNameByProcess : Boolean read fAutoFileName write fAutoFileName;
{$ENDIF}
property MaxRotateFiles : Integer read fMaxRotateFiles write fMaxRotateFiles;
property MaxFileSizeInMB : Integer read fMaxFileSizeInMB write fMaxFileSizeInMB;
property DailyRotate : Boolean read fDailyRotate write fDailyRotate;
property RotatedFilesPath : string read fRotatedFilesPath write fRotatedFilesPath;
property CompressRotatedFiles : Boolean read fCompressRotatedFiles write fCompressRotatedFiles;
property ShowEventType : Boolean read fShowEventTypes write fShowEventTypes;
property ShowHeaderInfo : Boolean read fShowHeaderInfo write fShowHeaderInfo;
property UnderlineHeaderEventType : Boolean read fUnderlineHeaderEventType write fUnderlineHeaderEventType;
property AutoFlush : Boolean read fAutoFlush write fAutoFlush;
end;
TRedisLoggerOptions = class(TLoggerOptions)
private
fHost : string;
fPort : Integer;
fDataBase : Integer;
fLogKey : string;
fMaxSize : Int64;
fPassword : string;
published
property Host : string read fHost write fHost;
property Port : Integer read fPort write fPort;
property DataBase : Integer read fDataBase write fDataBase;
property LogKey : string read fLogKey write fLogKey;
property MaxSize : Int64 read fMaxSize write fMaxSize;
property Password : string read fPassword write fPassword;
property OutputAsJson : Boolean read fOutputAsJson write fOutputAsJson;
property JsonOutputOptions : TJsonOutputOptions read fJsonOutputOptions write fJsonOutputOptions;
end;
TRestLoggerOptions = class(TLoggerOptions)
private
fURL : string;
fUserAgent : string;
published
property URL : string read fURL write fURL;
property UserAgent : string read fUserAgent write fUserAgent;
property JsonOutputOptions : TJsonOutputOptions read fJsonOutputOptions write fJsonOutputOptions;
end;
TEventLogLoggerOptions = class(TLoggerOptions)
private
fSource : string;
published
property Source : string read fSource write fSource;
end;
TTelegramLoggerOptions = class(TLoggerOptions)
private
fChannelName : string;
fChannelType : TTelegramChannelType;
fBotToken : string;
published
property ChannelName : string read fChannelName write fChannelName;
property ChannelType : TTelegramChannelType read fChannelType write fChannelType;
property BotToken : string read fBotToken write fBotToken;
end;
TSlackLoggerOptions = class(TLoggerOptions)
private
fChannelName : string;
fUserName : string;
fWebHookURL : string;
published
property ChannelName : string read fChannelName write fChannelName;
property UserName : string read fUserName write fUserName;
property WebHookURL : string read fWebHookURL write fWebHookURL;
end;
TEmailLoggerOptions = class(TLoggerOptions)
private
fSMTPConfig: TSMTPConfig;
fMailConfig: TMailConfig;
public
constructor Create; override;
destructor Destroy; override;
published
property SMTP : TSMTPConfig read fSMTPConfig write fSMTPConfig;
property Mail : TMailConfig read fMailConfig write fMailConfig;
end;
TSysLogLoggerOptions = class(TLoggerOptions)
private
fHost : string;
fPort : Integer;
fFacility : TSyslogFacility;
published
property Host : string read fHost write fHost;
property Port : Integer read fPort write fPort;
property Facility : TSyslogFacility read fFacility write fFacility;
end;
TElasticSearchLoggerOptions = class(TLoggerOptions)
private
fURL: string;
fIndexName: string;
fDocType : string;
public
constructor Create; override;
destructor Destroy; override;
published
property URL : string read fURL write fURL;
property IndexName : string read fIndexName write fIndexName;
property DocType : string read fDocType write fDocType;
end;
{$IFDEF MSWINDOWS}
TADODBLoggerOptions = class(TLoggerOptions)
private
fConnectionString : string;
fDBConfig : TDBConfig;
//fFieldsMapping : TFieldsMapping;
public
constructor Create; override;
destructor Destroy; override;
published
property ConnectionString : string read fConnectionString write fConnectionString;
property DBConfig : TDBConfig read fDBConfig write fDBConfig;
//property FieldsMapping : TFieldsMapping read fFieldsMapping write fFieldsMapping;
end;
{$ENDIF}
ILoggerBuilder<T> = interface
['{0A3594B0-7CE7-405F-9DA6-6ECC4A557B81}']
function MaxFailsToRestart(aNumFails : Integer) : T;
function MaxFailsToStop(aNumFails : Integer) : T;
function Environment(const aEnvironment : string) : T;
function IncludedInfo(aInfo : TIncludedLogInfo) : T;
function SendLimits(aLimits : TLogSendLimit) : T;
function LogLevel(aLevel : TLogLevel) : T;
function Enable : T;
end;
{$IFNDEF ANDROID}
ILoggerConsoleBuilder = interface
['{705773EA-FFE2-4A93-AB54-AACC9AB96BE1}']
function ShowEventColors(aValue : Boolean) : ILoggerConsoleBuilder;
function ShowTimeStamp(aValue : Boolean) : ILoggerConsoleBuilder;
function ShowEventType(aValue : Boolean) : ILoggerConsoleBuilder;
function UnderlineHeaderEventType(aValue : Boolean) : ILoggerConsoleBuilder;
function EventTypeColor(aEventType : TEventType; aColor : TConsoleColor) : ILoggerConsoleBuilder;
function Build : TConsoleLoggerOptions;
end;
TLoggerConsoleBuilder = class(TOptionsBuilder<TConsoleLoggerOptions>,ILoggerConsoleBuilder)
private
function ShowEventColors(aValue : Boolean) : ILoggerConsoleBuilder;
function ShowTimeStamp(aValue : Boolean) : ILoggerConsoleBuilder;
function ShowEventType(aValue : Boolean) : ILoggerConsoleBuilder;
function UnderlineHeaderEventType(aValue : Boolean) : ILoggerConsoleBuilder;
function EventTypeColor(aEventType : TEventType; aColor : TConsoleColor) : ILoggerConsoleBuilder;
function Build : TConsoleLoggerOptions;
public
class function GetBuilder : ILoggerConsoleBuilder;
end;
{$ENDIF}
ILoggerBuilder = interface
['{4EF49E04-9C4E-47AD-88C6-6D65D5427741}']
{$IFNDEF ANDROID}
function AddConsole(aOptions : TConsoleLoggerOptions) : ILoggerBuilder; overload;
function AddConsole(aConfigureProc : TLoggerOptionsProc<TConsoleLoggerOptions>) : ILoggerBuilder; overload;
{$ENDIF}
function AddFile(aConfigureProc: TLoggerOptionsProc<TFileLoggerOptions>) : ILoggerBuilder;
function AddRedis(aConfigureProc : TLoggerOptionsProc<TRedisLoggerOptions>) : ILoggerBuilder;
function AddRest(aOptions : TLoggerOptionsProc<TRestLoggerOptions>) : ILoggerBuilder;
function AddTelegram(aConfigureProc: TLoggerOptionsProc<TTelegramLoggerOptions>): ILoggerBuilder;
function AddSlack(aConfigureProc: TLoggerOptionsProc<TSlackLoggerOptions>): ILoggerBuilder;
function AddEmail(aConfigureProc : TLoggerOptionsProc<TEmailLoggerOptions>): ILoggerBuilder;
function AddElasticSearch(aConfigureProc : TLoggerOptionsProc<TElasticSearchLoggerOptions>): ILoggerBuilder;
{$IFDEF MSWINDOWS}
function AddEventLog(aConfigureProc: TLoggerOptionsProc<TEventLogLoggerOptions>): ILoggerBuilder;
function AddADODB(aConfigureProc: TLoggerOptionsProc<TADODBLoggerOptions>): ILoggerBuilder;
{$ENDIF}
function AddSysLog(aConfigureProc: TLoggerOptionsProc<TSysLogLoggerOptions> = nil): ILoggerBuilder;
function Build : ILogger;
end;
TLoggerOptionsFormat = (ofJSON, ofYAML);
TLoggerBuilder = class(TInterfacedObject,ILoggerBuilder)
type
TLoggerProviderFactory = class
class function NewLoggerInstance(const aName : string) : TLogProviderBase;
end;
private
fUseOptionsFile : Boolean;
fOptionsFilename : string;
fOptionContainer : TOptionsContainer;
fCreateIfNotExists : Boolean;
constructor Create; overload;
constructor Create(aOptionsFormat : TLoggerOptionsFormat; aCreateConfigFileIfNotExists : Boolean = True; aOptionsFilename : string = ''); overload;
procedure AddOptions(aOptionsFormat : TLoggerOptionsFormat);
procedure AddOptionClass(const aName : string);
procedure LoadConfig;
procedure AddProvider(aProvider : TLogProviderBase);
function GetEnvironment : string;
protected
fLogger : TQuickLogger;
{$IFNDEF ANDROID}
function AddConsole(aOptions : TConsoleLoggerOptions) : ILoggerBuilder; overload;
function AddConsole(aConfigureProc : TLoggerOptionsProc<TConsoleLoggerOptions>) : ILoggerBuilder; overload;
{$ENDIF}
function AddFile(aConfigureProc: TLoggerOptionsProc<TFileLoggerOptions>): ILoggerBuilder;
function AddRedis(aConfigureProc : TLoggerOptionsProc<TRedisLoggerOptions>) : ILoggerBuilder;
function AddRest(aConfigureProc : TLoggerOptionsProc<TRestLoggerOptions>) : ILoggerBuilder;
function AddTelegram(aConfigureProc: TLoggerOptionsProc<TTelegramLoggerOptions>): ILoggerBuilder;
function AddSlack(aConfigureProc: TLoggerOptionsProc<TSlackLoggerOptions>): ILoggerBuilder;
function AddEmail(aConfigureProc: TLoggerOptionsProc<TEmailLoggerOptions>): ILoggerBuilder;
function AddElasticSearch(aConfigureProc : TLoggerOptionsProc<TElasticSearchLoggerOptions>): ILoggerBuilder;
{$IFDEF MSWINDOWS}
function AddEventLog(aConfigureProc: TLoggerOptionsProc<TEventLogLoggerOptions>): ILoggerBuilder;
function AddADODB(aConfigureProc: TLoggerOptionsProc<TADODBLoggerOptions>): ILoggerBuilder;
{$ENDIF}
function AddSysLog(aConfigureProc: TLoggerOptionsProc<TSysLogLoggerOptions> = nil): ILoggerBuilder;
function Build : ILogger;
public
destructor Destroy; override;
class function GetBuilder(aUseConfigFile : Boolean) : ILoggerBuilder; overload;
class function GetBuilder(aOptionsFormat : TLoggerOptionsFormat = ofYAML; aCreateConfigFileIfNotExists : Boolean = True) : ILoggerBuilder; overload;
class function GetBuilder(aOptionsFormat : TLoggerOptionsFormat; aCreateConfigFileIfNotExists : Boolean; aOptionsFilename : string) : ILoggerBuilder; overload;
end;
ELoggerConfigError = class(Exception);
const
LOG_ONLYERRORS = [etHeader,etInfo,etError,etCritical,etException];
LOG_ERRORSANDWARNINGS = [etHeader,etInfo,etWarning,etError,etCritical,etException];
LOG_BASIC = [etInfo,etSuccess,etWarning,etError,etCritical,etException];
LOG_ALL = [etHeader,etInfo,etSuccess,etDone,etWarning,etError,etCritical,etException,etCustom1,etCustom2];
LOG_TRACE = [etHeader,etInfo,etSuccess,etDone,etWarning,etError,etCritical,etException,etTrace];
LOG_DEBUG = [etHeader,etInfo,etSuccess,etDone,etWarning,etError,etCritical,etException,etTrace,etDebug];
LOG_VERBOSE : TLogLevel = [Low(TEventType)..high(TEventType)];
implementation
{ TQuickLogger }
constructor TQuickLogger.Create;
begin
fLogger := TLogger.Create;
Init;
end;
destructor TQuickLogger.Destroy;
begin
fLogger.Free;
inherited;
end;
procedure TQuickLogger.Init;
begin
//if IsDebug then GlobalLogConsoleProvider.LogLevel := LOG_DEBUG;
//add default logger before load settings from file
//Logger.Providers.Add(GlobalLogConsoleProvider);
//GlobalLogConsoleProvider.Name := 'default';
//GlobalLogConsoleProvider.Enabled := True;
end;
function TQuickLogger.Providers: TLogProviderList;
begin
Result := fLogger.Providers;
end;
procedure TQuickLogger.Info(const aMsg: string);
begin
fLogger.Info(aMsg);
end;
procedure TQuickLogger.Info(const aMsg: string; aValues: array of const);
begin
fLogger.Info(aMsg,aValues);
end;
procedure TQuickLogger.Succ(const aMsg: string);
begin
fLogger.Succ(aMsg);
end;
procedure TQuickLogger.Succ(const aMsg: string; aParams: array of const);
begin
fLogger.Succ(aMsg,aParams);
end;
procedure TQuickLogger.Done(const aMsg: string);
begin
fLogger.Done(aMsg);
end;
procedure TQuickLogger.Done(const aMsg: string; aValues: array of const);
begin
fLogger.Done(aMsg,aValues);
end;
procedure TQuickLogger.Warn(const aMsg: string);
begin
fLogger.Warn(aMsg);
end;
procedure TQuickLogger.Warn(const aMsg: string; aValues: array of const);
begin
fLogger.Warn(aMsg,aValues);
end;
procedure TQuickLogger.Error(const aMsg: string);
begin
fLogger.Error(aMsg);
end;
procedure TQuickLogger.Error(const aMsg: string; aValues: array of const);
begin
fLogger.Error(aMsg,aValues);
end;
procedure TQuickLogger.Critical(const aMsg: string);
begin
fLogger.Critical(aMsg);
end;
procedure TQuickLogger.Critical(const aMsg: string; aValues: array of const);
begin
fLogger.Critical(aMsg,aValues);
end;
procedure TQuickLogger.Trace(const aMsg: string);
begin
fLogger.Trace(aMsg);
end;
procedure TQuickLogger.Trace(const aMsg: string; aValues: array of const);
begin
fLogger.Trace(aMsg,aValues);
end;
procedure TQuickLogger.Debug(const aMsg: string);
begin
fLogger.Debug(aMsg);
end;
procedure TQuickLogger.Debug(const aMsg: string; aValues: array of const);
begin
fLogger.Debug(aMsg,aValues);
end;
procedure TQuickLogger.&Except(const aMsg: string; aValues: array of const);
begin
fLogger.&Except(aMsg,aValues);
end;
procedure TQuickLogger.&Except(const aMsg: string; aValues: array of const; const aException, aStackTrace: string);
begin
fLogger.&Except(aMsg,aValues,aException,aStacktrace);
end;
procedure TQuickLogger.&Except(const aMsg, aException, aStackTrace: string);
begin
fLogger.&Except(aMsg,aException,aStackTrace);
end;
{ TLoggerConsoleProviderBuilder }
{$IFNDEF ANDROID}
class function TLoggerConsoleBuilder.GetBuilder: ILoggerConsoleBuilder;
begin
Result := TLoggerConsoleBuilder.Create;
end;
function TLoggerConsoleBuilder.Build: TConsoleLoggerOptions;
begin
Result := Self.Options;
end;
function TLoggerConsoleBuilder.EventTypeColor(aEventType: TEventType; aColor: TConsoleColor): ILoggerConsoleBuilder;
begin
end;
function TLoggerConsoleBuilder.ShowEventColors(aValue: Boolean): ILoggerConsoleBuilder;
begin
end;
function TLoggerConsoleBuilder.ShowEventType(aValue: Boolean): ILoggerConsoleBuilder;
begin
end;
function TLoggerConsoleBuilder.ShowTimeStamp(aValue: Boolean): ILoggerConsoleBuilder;
begin
end;
function TLoggerConsoleBuilder.UnderlineHeaderEventType(aValue: Boolean): ILoggerConsoleBuilder;
begin
end;
{$ENDIF}
{ TLoggerBuilder }
constructor TLoggerBuilder.Create;
begin
fOptionsFilename := '';
fCreateIfNotExists := False;
fUseOptionsFile := False;
fLogger := TQuickLogger.Create;
end;
constructor TLoggerBuilder.Create(aOptionsFormat : TLoggerOptionsFormat; aCreateConfigFileIfNotExists : Boolean = True; aOptionsFilename : string = '');
begin
fUseOptionsFile := True;
fOptionsFilename := aOptionsFilename;
fCreateIfNotExists := aCreateConfigFileIfNotExists;
fLogger := TQuickLogger.Create;
//load settings
AddOptions(aOptionsFormat);
end;
destructor TLoggerBuilder.Destroy;
begin
if Assigned(fOptionContainer) then fOptionContainer.Free;
inherited;
end;
//builder without save to file
class function TLoggerBuilder.GetBuilder(aUseConfigFile : Boolean) : ILoggerBuilder;
begin
if aUseConfigFile then Result := GetBuilder
else Result := TLoggerBuilder.Create;
end;
class function TLoggerBuilder.GetBuilder(aOptionsFormat : TLoggerOptionsFormat = ofYAML; aCreateConfigFileIfNotExists : Boolean = True) : ILoggerBuilder;
begin
Result := GetBuilder(aOptionsFormat,aCreateConfigFileIfNotExists,'');
end;
class function TLoggerBuilder.GetBuilder(aOptionsFormat: TLoggerOptionsFormat; aCreateConfigFileIfNotExists: Boolean; aOptionsFilename: string): ILoggerBuilder;
begin
Result := TLoggerBuilder.Create(aOptionsFormat,aCreateConfigFileIfNotExists,aOptionsFilename);
end;
function TLoggerBuilder.GetEnvironment: string;
begin
Result := GetEnvironmentVariable('CORE_ENVIRONMENT');
end;
procedure TLoggerBuilder.LoadConfig;
var
oplogger : TLoggerOptions;
i : Integer;
logprovider : TLogProviderBase;
iprovider : ILogProvider;
sections : TArray<string>;
sectionName : string;
begin
if not fUseOptionsFile then Exit;
for iprovider in fLogger.Providers do iprovider.Stop;
fLogger.Providers.Clear;
//get options in file
if fOptionContainer.GetFileSectionNames(sections) then
begin
for sectionName in sections do
begin
AddOptionClass(sectionName);
end;
end;
//load options
fOptionContainer.Load;
for i := 0 to fOptionContainer.Count - 1 do
begin
oplogger := fOptionContainer.Items[i] as TLoggerOptions;
logprovider := TLoggerProviderFactory.NewLoggerInstance(oplogger.Name);
TObjMapper.Map(oplogger,logprovider);
fLogger.Providers.Add(logprovider);
{$IFDEF DEBUG_LOGGING}
TDebugger.Trace(Self,Format('Loaded Logger provider %s',[logprovider.Name]));
{$ENDIF}
end;
{$IFDEF DEBUG_LOGGING}
TDebugger.Trace(Self,Format('Loaded %d logger providers',[fLogger.Providers.Count]));
{$ENDIF}
end;
procedure TLoggerBuilder.AddProvider(aProvider : TLogProviderBase);
begin
fLogger.Providers.Add(aProvider);
{$IFDEF DEBUG_LOGGING}
TDebugger.Trace(Self,Format('Added Logger provider %s',[aProvider.Name]));
{$ENDIF}
//loggerConsole.Enabled := True;
end;
{$IFNDEF ANDROID}
function TLoggerBuilder.AddConsole(aConfigureProc: TLoggerOptionsProc<TConsoleLoggerOptions>): ILoggerBuilder;
var
options : TConsoleLoggerOptions;
loggerConsole : TLogConsoleProvider;
begin
Result := Self;
if fUseOptionsFile then
begin
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TConsoleLoggerOptions,'Console')) then Exit;
options := fOptionContainer.AddSection(TConsoleLoggerOptions,'Console') as TConsoleLoggerOptions;
end
else options := TConsoleLoggerOptions.Create;
loggerConsole := TLogConsoleProvider.Create;
loggerConsole.Name := options.Name;
TObjMapper.Map(loggerConsole,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerConsole);
AddProvider(loggerConsole);
if not fUseOptionsFile then options.Free;
end;
function TLoggerBuilder.AddConsole(aOptions: TConsoleLoggerOptions): ILoggerBuilder;
begin
fOptionContainer.AddOption(aOptions);
end;
{$ENDIF}
function TLoggerBuilder.AddFile(aConfigureProc: TLoggerOptionsProc<TFileLoggerOptions>): ILoggerBuilder;
var
options : TFileLoggerOptions;
loggerFile : TLogFileProvider;
begin
Result := Self;
if fUseOptionsFile then
begin
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TFileLoggerOptions,'File')) then Exit;
options := fOptionContainer.AddSection(TFileLoggerOptions,'File') as TFileLoggerOptions;
end
else options := TFileLoggerOptions.Create;
loggerFile := TLogFileProvider.Create;
loggerFile.Name := options.Name;
TObjMapper.Map(loggerFile,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerFile);
AddProvider(loggerFile);
{$IFDEF ANDROID}
options.FileName := TPath.GetDocumentsPath + PathDelim + TPath.GetFileNameWithoutExtension(path.EXEPATH) + '.log';
{$ENDIF}
if not fUseOptionsFile then options.Free;
end;
function TLoggerBuilder.AddRedis(aConfigureProc: TLoggerOptionsProc<TRedisLoggerOptions>): ILoggerBuilder;
var
options : TRedisLoggerOptions;
loggerRedis : TLogRedisProvider;
begin
Result := Self;
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TRedisLoggerOptions,'Redis')) then Exit;
options := fOptionContainer.AddSection(TRedisLoggerOptions,'Redis') as TRedisLoggerOptions;
loggerRedis := TLogRedisProvider.Create;
loggerRedis.Name := options.Name;
TObjMapper.Map(loggerRedis,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerRedis);
AddProvider(loggerRedis);
if not fUseOptionsFile then options.Free;
end;
function TLoggerBuilder.AddRest(aConfigureProc: TLoggerOptionsProc<TRestLoggerOptions>): ILoggerBuilder;
var
options : TRestLoggerOptions;
loggerRest : TLogRestProvider;
begin
Result := Self;
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TRestLoggerOptions,'Rest')) then Exit;
options := fOptionContainer.AddSection(TRestLoggerOptions,'Rest') as TRestLoggerOptions;
loggerRest := TLogRestProvider.Create;
loggerRest.Name := options.Name;
TObjMapper.Map(loggerRest,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerRest);
AddProvider(loggerRest);
if not fUseOptionsFile then options.Free;
end;
{$IFDEF MSWINDOWS}
function TLoggerBuilder.AddEventLog(aConfigureProc: TLoggerOptionsProc<TEventLogLoggerOptions>): ILoggerBuilder;
var
options : TEventLogLoggerOptions;
loggerEventLog : TLogEventLogProvider;
begin
Result := Self;
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TEventLogLoggerOptions,'EventLog')) then Exit;
options := fOptionContainer.AddSection(TEventLogLoggerOptions,'EventLog') as TEventLogLoggerOptions;
loggerEventLog := TLogEventLogProvider.Create;
loggerEventLog.Name := options.Name;
TObjMapper.Map(loggerEventLog,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerEventLog);
AddProvider(loggerEventLog);
if not fUseOptionsFile then options.Free;
end;
{$ENDIF}
function TLoggerBuilder.AddTelegram(aConfigureProc: TLoggerOptionsProc<TTelegramLoggerOptions>): ILoggerBuilder;
var
options : TTelegramLoggerOptions;
loggerTelegram : TLogTelegramProvider;
begin
Result := Self;
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TTelegramLoggerOptions,'Telegram')) then Exit;
options := fOptionContainer.AddSection(TTelegramLoggerOptions,'Telegram') as TTelegramLoggerOptions;
loggerTelegram := TLogTelegramProvider.Create;
loggerTelegram.Name := options.Name;
TObjMapper.Map(loggerTelegram,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerTelegram);
AddProvider(loggerTelegram);
if not fUseOptionsFile then options.Free;
end;
function TLoggerBuilder.AddSlack(aConfigureProc: TLoggerOptionsProc<TSlackLoggerOptions>): ILoggerBuilder;
var
options : TSlackLoggerOptions;
loggerSlack : TLogSlackProvider;
begin
Result := Self;
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TSlackLoggerOptions,'Slack')) then Exit;
options := fOptionContainer.AddSection(TSlackLoggerOptions,'Slack') as TSlackLoggerOptions;
loggerSlack := TLogSlackProvider.Create;
loggerSlack.Name := options.Name;
TObjMapper.Map(loggerSlack,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerSlack);
AddProvider(loggerSlack);
if not fUseOptionsFile then options.Free;
end;
function TLoggerBuilder.AddElasticSearch(aConfigureProc: TLoggerOptionsProc<TElasticSearchLoggerOptions>): ILoggerBuilder;
var
options : TElasticSearchLoggerOptions;
loggerElastic : TLogElasticSearchProvider;
begin
Result := Self;
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TElasticSearchLoggerOptions,'ElasticSearch')) then Exit;
options := fOptionContainer.AddSection(TElasticSearchLoggerOptions,'ElasticSearch') as TElasticSearchLoggerOptions;
loggerElastic := TLogElasticSearchProvider.Create;
loggerElastic.Name := options.Name;
TObjMapper.Map(loggerElastic,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerElastic);
AddProvider(loggerElastic);
if not fUseOptionsFile then options.Free;
end;
function TLoggerBuilder.AddEmail(aConfigureProc: TLoggerOptionsProc<TEmailLoggerOptions>): ILoggerBuilder;
var
options : TEmailLoggerOptions;
loggerEmail : TLogEmailProvider;
begin
Result := Self;
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TEmailLoggerOptions,'Email')) then Exit;
options := fOptionContainer.AddSection(TEmailLoggerOptions,'Email') as TEmailLoggerOptions;
loggerEmail := TLogEmailProvider.Create;
loggerEmail.Name := options.Name;
TObjMapper.Map(loggerEmail,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerEmail);
AddProvider(loggerEmail);
if not fUseOptionsFile then options.Free;
end;
function TLoggerBuilder.AddSysLog(aConfigureProc: TLoggerOptionsProc<TSysLogLoggerOptions> = nil): ILoggerBuilder;
var
options : TSysLogLoggerOptions;
loggerSyslog : TLogSysLogProvider;
begin
Result := Self;
if (fUseOptionsFile) and (fOptionContainer <> nil) then
begin
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TSysLogLoggerOptions,'SysLog')) then Exit;
options := fOptionContainer.AddSection(TSysLogLoggerOptions,'SysLog') as TSysLogLoggerOptions;
end
else options := TSysLogLoggerOptions.Create;
loggerSyslog := TLogSysLogProvider.Create;
loggerSyslog.Name := options.Name;
TObjMapper.Map(loggerSyslog,options);
if Assigned(aConfigureProc) then aConfigureProc(options);
TObjMapper.Map(options,loggerSyslog);
AddProvider(loggerSyslog);
if not fUseOptionsFile then options.Free;
end;
{$IFDEF MSWINDOWS}
function TLoggerBuilder.AddADODB(aConfigureProc: TLoggerOptionsProc<TADODBLoggerOptions>): ILoggerBuilder;
var
options : TADODBLoggerOptions;
loggerADODB : TLogADODBProvider;
begin
Result := Self;
if (fOptionContainer.IsLoaded) and (fOptionContainer.ExistsSection(TADODBLoggerOptions,'ADODB')) then Exit;
options := fOptionContainer.AddSection(TADODBLoggerOptions,'ADODB') as TADODBLoggerOptions;
loggerADODB := TLogADODBProvider.Create;
loggerADODB.Name := options.Name;
TObjMapper.Map(loggerADODB,options);
aConfigureProc(options);
TObjMapper.Map(options,loggerADODB);
AddProvider(loggerADODB);
if not fUseOptionsFile then options.Free;
end;
{$ENDIF}
procedure TLoggerBuilder.AddOptionClass(const aName: string);
var
provname : string;
begin
provname := aName.ToLower;
if provname = 'console' then fOptionContainer.AddSection<TConsoleLoggerOptions>('Console')
else if provname = 'file' then fOptionContainer.AddSection<TFileLoggerOptions>('File')
else if provname = 'redis' then fOptionContainer.AddSection<TRedisLoggerOptions>('Redis')
else if provname = 'rest' then fOptionContainer.AddSection<TRestLoggerOptions>('Rest')
else if provname = 'telegram' then fOptionContainer.AddSection<TTelegramLoggerOptions>('Telegram')
else if provname = 'slack' then fOptionContainer.AddSection<TSlackLoggerOptions>('Slack')
else if provname = 'email' then fOptionContainer.AddSection<TEmailLoggerOptions>('Email')
else if provname = 'elasticsearch' then fOptionContainer.AddSection<TElasticSearchLoggerOptions>('ElasticSearch')
{$IFDEF MSWINDOWS}
else if provname = 'eventlog' then fOptionContainer.AddSection<TEventLogLoggerOptions>('EventLog')
else if provname = 'adodb' then fOptionContainer.AddSection<TADODBLoggerOptions>('ADODB')
{$ELSE}
else if (provname = 'eventlog') or (provname = 'adodb') then Exit
{$ENDIF}
else if provname = 'syslog' then fOptionContainer.AddSection<TSysLogLoggerOptions>('SysLog')
else raise Exception.CreateFmt('Logger provider "%S" is not a valid provider!',[aName]);
end;
procedure TLoggerBuilder.AddOptions(aOptionsFormat : TLoggerOptionsFormat);
var
filename : string;
iserializer : IFileOptionsSerializer;
environment : string;
opfilename : string;
begin
environment := GetEnvironment;
if not environment.IsEmpty then environment := '.' + environment;
if fOptionsFilename.IsEmpty then opfilename := 'QuickLogger'
else opfilename := fOptionsFilename;
if aOptionsFormat = TLoggerOptionsFormat.ofJSON then
begin
{$IFNDEF ANDROID}
if opfilename.Contains(PathDelim) then filename := opfilename
else filename := path.EXEPATH + PathDelim + opfilename + environment + '.json';
{$ELSE}
fileName := TPath.GetDocumentsPath + PathDelim + opfilename + environment + '.json';
{$ENDIF}
iserializer := TJsonOptionsSerializer.Create(filename);
end
else if aOptionsFormat = TLoggerOptionsFormat.ofYAML then
begin
{$IFNDEF ANDROID}
if opfilename.Contains(PathDelim) then filename := opfilename
else filename := path.EXEPATH + PathDelim + opfilename + environment + '.yml';
{$ELSE}
fileName := TPath.GetDocumentsPath + PathDelim + opfilename + environment + '.yml';
{$ENDIF}
iserializer := TYamlOptionsSerializer.Create(filename);
end
else raise ELoggerConfigError.Create('Logger Options Serializer not recognized!');
fOptionContainer := TFileOptionsContainer.Create(iserializer,False);
if FileExists(filename) then
begin
{$IFDEF DEBUG_LOGGING}
TDebugger.Trace(Self,Format('Loading Logger settings from "%s"',[filename]));
{$ENDIF}
//load config
LoadConfig;
end
else
begin
{$IFDEF DEBUG_LOGGING}
TDebugger.Trace(Self,Format('Autocreate Logger settings "%s"',[filename]));
{$ENDIF}
end;
end;
function TLoggerBuilder.Build: ILogger;
begin
Result := fLogger;
if fCreateIfNotExists then fOptionContainer.Save;
end;
{ TLoggerProviderOptions }
constructor TLoggerOptions.Create;
begin
inherited Create;
fFormatSettings.DateSeparator := '/';
fFormatSettings.TimeSeparator := ':';
fFormatSettings.ShortDateFormat := 'DD-MM-YYY HH:NN:SS';
fFormatSettings.ShortTimeFormat := 'HH:NN:SS';
fTimePrecission := False;
fSendLimits := TLogSendLimit.Create;
fAppName := GetAppName;
fMaxFailsToRestart := 2;
fMaxFailsToStop := 0;
fEnabled := False;
fUsesQueue := True;
fEventTypeNames := DEF_EVENTTYPENAMES;
fEnvironment := '';
fPlatformInfo := '';
fIncludedInfo := [iiAppName,iiHost];
fJsonOutputOptions := TJsonOutputOptions.Create;
fJsonOutputOptions.UseUTCTime := False;
fJsonOutputOptions.TimeStampName := 'timestamp';
end;
destructor TLoggerOptions.Destroy;
begin
fSendLimits.Free;
fJsonOutputOptions.Free;
inherited;
end;
{ TLoggerBuilder.TLoggerProviderFactory }
class function TLoggerBuilder.TLoggerProviderFactory.NewLoggerInstance(const aName: string): TLogProviderBase;
var
provname : string;
begin
provname := aName.ToLower;
{$IFNDEF ANDROID}
if provname = 'console' then Result := TLogConsoleProvider.Create
else {$ENDIF} if provname = 'file' then Result := TLogFileProvider.Create
else if provname = 'redis' then Result := TLogRedisProvider.Create
else if provname = 'rest' then Result := TLogRestProvider.Create
else if provname = 'telegram' then Result := TLogTelegramProvider.Create
else if provname = 'slack' then Result := TLogSlackProvider.Create
else if provname = 'email' then Result := TLogEmailProvider.Create
else if provname = 'elasticsearch' then Result := TLogElasticSearchProvider.Create
{$IFDEF MSWINDOWS}
else if provname = 'eventlog' then Result := TLogEventLogProvider.Create
else if provname = 'adodb' then Result := TLogADODBProvider.Create
{$ENDIF}
else if provname = 'syslog' then Result := TLogSysLogProvider.Create
else raise Exception.CreateFmt('Logger provider "%S" is not a valid provider!',[aName]);
end;
{ TADODBLoggerOptions }
{$IFDEF MSWINDOWS}
constructor TADODBLoggerOptions.Create;
begin
inherited;
fDBConfig := TDBConfig.Create;
end;
destructor TADODBLoggerOptions.Destroy;
begin
fDBConfig.Free;
inherited;
end;
{$ENDIF}
{ TEmailLoggerOptions }
constructor TEmailLoggerOptions.Create;
begin
inherited;
fSMTPConfig := TSMTPConfig.Create;
fMailConfig := TMailConfig.Create;
end;
destructor TEmailLoggerOptions.Destroy;
begin
fSMTPConfig.Free;
fMailConfig.Free;
inherited;
end;
{ TElasticSearchLoggerOptions }
constructor TElasticSearchLoggerOptions.Create;
begin
inherited;
fURL := 'http://127.0.0.1:9200';
fIndexName := 'logger';
fDocType := 'doc';
end;
destructor TElasticSearchLoggerOptions.Destroy;
begin
inherited;
end;
end.
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wzdlsoft/QuickCore.git
git@gitee.com:wzdlsoft/QuickCore.git
wzdlsoft
QuickCore
QuickCore
master

搜索帮助