unit Common.Logging; interface uses Generics.Collections; type ILog = interface; ILogAppender = interface; ILogger = interface ['{4D667DD2-BE11-496B-B92A-C47E03520BD6}'] procedure Log(logLevel: integer; Msg: string); overload; procedure Log(logLevel: integer; Log: ILog); overload; procedure AddAppender(ALogAppender: ILogAppender); function Appenders: TArray<ILogAppender>; end; ILogAppender = interface ['{A3B7D6FB-C75F-4BEF-8797-907B6FDAD5D2}'] procedure Send(logLevel: integer; Log: ILog); end; ILog = interface ['{8E9C6580-C099-47C0-8B1B-6D7A28EC4FA3}'] function GetMessage: string; end; TLogger = class( TInterfacedObject, ILogger ) strict private FAppenders: TList<ILogAppender>; public constructor Create; overload; constructor Create(ALogger: ILogger); overload; destructor Destroy; override; procedure Log(logLevel: integer; Msg: string); overload; procedure Log(logLevel: integer; Log: ILog); overload; procedure AddAppender(ALogAppender: ILogAppender); function Appenders: TArray<ILogAppender>; end; TLogMessage = class( TInterfacedObject, ILog ) private FMsg: string; public constructor Create(AMsg: string); function GetMessage: string; end; function Logger: ILogger; implementation var _Logger: ILogger; function Logger: ILogger; begin Result := _Logger; end; { TLogMessage } constructor TLogMessage.Create(AMsg: string); begin FMsg := AMsg; end; function TLogMessage.GetMessage: string; begin Result := FMsg; end; { TLogger } procedure TLogger.AddAppender(ALogAppender: ILogAppender); begin FAppenders.Add(ALogAppender); end; function TLogger.Appenders: TArray<ILogAppender>; var I: integer; begin SetLength(Result, FAppenders.Count); for I := 0 to FAppenders.Count - 1 do Result[I] := FAppenders[I]; end; constructor TLogger.Create(ALogger: ILogger); var Appender: ILogAppender; begin FAppenders := TList<ILogAppender>.Create; if ALogger <> nil then for Appender in ALogger.Appenders do AddAppender(Appender); end; constructor TLogger.Create; begin Create(nil); end; destructor TLogger.Destroy; begin FAppenders.Free; inherited; end; procedure TLogger.Log(logLevel: integer; Log: ILog); var Appender: ILogAppender; begin for Appender in FAppenders do Appender.Send(logLevel, Log); end; procedure TLogger.Log(logLevel: integer; Msg: string); begin Log(logLevel, TLogMessage.Create(Msg)); end; initialization _Logger := TLogger.Create; end.