AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Open Source "Logging Facade" für Pascal auf Github
Thema durchsuchen
Ansicht
Themen-Optionen

Open Source "Logging Facade" für Pascal auf Github

Ein Thema von mjustin · begonnen am 27. Jan 2016 · letzter Beitrag vom 7. Feb 2016
Antwort Antwort
Seite 1 von 2  1 2      
mquadrat

Registriert seit: 13. Feb 2004
1.113 Beiträge
 
Delphi XE2 Professional
 
#1

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 27. Jan 2016, 16:32
Werde ich mir mal anschauen. Ich sehe zwar nicht, dass wir in absehbarer Zeit von Log4D weg wechseln, aber die Möglichkeit zu haben kann ja nie schaden. Wobei ich aktuell ehrlich gesagt, auch nicht wüsste, wohin wir wechseln sollten
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.164 Beiträge
 
Delphi 12 Athens
 
#2

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 29. Jan 2016, 12:25
Sieht interessant aus,

aber was ich mich bei dem Thema immer frage:
Gibt es in Delphi eigentlich die Möglichkeit eine "leere" Prozedur zu definieren,
als Beispiel mal das Object.Free

Delphi-Quellcode:
procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
  if Self <> nil then
    Destroy;
{$ENDIF}
end;
So das man beim Aufruf nicht immer hier reinspreingen muss, wenn nichts drin steht.

Also Obj.Free; wird doch immer aufgerufen, mit ein paar Zeilen Assembler für in- out-management.

Aber schön wäre doch eine Debug Prozedur die gar nicht erst kompiliert wird, oder wenigstens ein nop,
(natürlich ohne Fehlermeldungen), wenn das DEBUG Define nicht vorhanden ist.

Ich denke da an soetwas wie die Defines/Macros von CPP, diese werden beim PreCompiler einfach ignotiert
wenn nichts drinsteht.

Also
bei DEBUG Define:
Log.Debug('Blah'); // wird aufgerufen und macht ihr Ding

ohne DEBUG Define:
Log.Debug('Blah'); // wird einfach ignoriert, und muss nicht erst rein- rausgesprungen werden

Geht das, evtl. mit Interfaces ?


Rollo
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.609 Beiträge
 
Delphi 12 Athens
 
#3

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 29. Jan 2016, 12:51
Du kannst so etwas mit inline erreichen. Ohne das DEFINE Log sieht man schon keinen blauen Punkt for dem Log-Aufruf in Main.

Delphi-Quellcode:
unit Unit58;

interface

procedure Log(AText: string); inline;

implementation

{.$DEFINE Log}

procedure Log(AText: string);
begin
  {$IFDEF Log}
  Writeln(AText);
  {$ENDIF}
end;


end.
Delphi-Quellcode:
uses
  Unit58 in 'Unit58.pas';

procedure Main;
begin
  Log('Hallo Welt');
  Writeln('Wie geht''s?');
  Readln;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.008 Beiträge
 
Delphi 2009 Professional
 
#4
  Alt 29. Jan 2016, 16:44
Du kannst so etwas mit inline erreichen. Ohne das DEFINE Log sieht man schon keinen blauen Punkt for dem Log-Aufruf in Main.
Leider funktioniert das hier bei Delphi 2009 nicht im Fall von Interface - Methoden, der blaue Punkt bleibt bestehen:

Delphi-Quellcode:
program Project201601291;

{$APPTYPE CONSOLE}

type
  ITest = interface['{76BA1F8A-D171-4817-BB3D-337295B03CE0}']
    procedure Log;
  end;

  TTest = class(TInterfacedObject, ITest)
  public
    procedure Log; inline;
  end;

var
  T: ITest;

procedure TTest.Log;
begin
end;

begin
  T := TTest.Create;
  T.Log;
end.
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.609 Beiträge
 
Delphi 12 Athens
 
#5

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 29. Jan 2016, 19:13
Leider funktioniert das hier bei Delphi 2009 nicht im Fall von Interface - Methoden, der blaue Punkt bleibt bestehen:
Das ist in der Tat so, denn die Interface-Methode ist ja auch nicht inline (wie auch). Da kann der Compiler nicht anders und ruft das dann eben auf.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
mquadrat

Registriert seit: 13. Feb 2004
1.113 Beiträge
 
Delphi XE2 Professional
 
#6

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 30. Jan 2016, 08:45
Als ich den Post gesehen habe, habe ich auch erst mal an http://www.php-fig.org/ gedacht. In so einem Projekt kann man wunderbar übergreifende Interfaces entwickeln. Dazu dann noch eine Art Selbstverpflichtung für OpenSource Packages ala https://thephpleague.com/de/ und Delphinus-Support.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.609 Beiträge
 
Delphi 12 Athens
 
#7

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 30. Jan 2016, 09:49
Leider funktioniert das hier bei Delphi 2009 nicht im Fall von Interface - Methoden, der blaue Punkt bleibt bestehen:
Noch was: Mal abgesehen davon, daß inline in der DPR nicht funktioniert, könnte man für das Logger-Interface auch einen Wrapper-Record definieren, der die Aufrufe unter IFDEF an das Interface weiterreicht. Damit wird keine der inlined Record-Methoden aufgerufen, wenn das entsprechende IFDEF nicht zutrifft. Einziger etwas unschöner Nebeneffekt ist, daß eine nicht verwendete Variable T in Main angemeckert wird.

Delphi-Quellcode:
unit Unit58;

interface

{.$DEFINE Log}

type
  ILog = interface
  ['{76BA1F8A-D171-4817-BB3D-337295B03CE0}']
    procedure Log(AText: string);
  end;

  TLog = record
  private
    {$IFDEF Log}
    FLog: ILog;
    {$ENDIF}
  public
    procedure Init(const AName: string); inline;
    procedure Log(AText: string); inline;
  end;

implementation

type
  TLogConsole = class(TInterfacedObject, ILog)
  public
    procedure Log(AText: string);
  end;

procedure TLogConsole.Log(AText: string);
begin
  Writeln(AText);
end;

procedure TLog.Init(const AName: string);
begin
  {$IFDEF Log}
  // der Einfachheit halber
  FLog := TLogConsole.Create;
  {$ENDIF}
end;

procedure TLog.Log(AText: string);
begin
  {$IFDEF Log}
  if FLog <> nil then begin
    FLog.Log(AText);
  end;
  {$ENDIF}
end;

end.
Delphi-Quellcode:
program Project67;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  Unit58 in 'Unit58.pas';

procedure Main;
var
  T: TLog;
begin
  T.Init('TLogConsole');
  T.Log('Hallo Welt');
  Writeln('Wie geht''s?');
  Readln;
end;

begin
  Main;
end.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.008 Beiträge
 
Delphi 2009 Professional
 
#8

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 30. Jan 2016, 12:50
Noch was: Mal abgesehen davon, daß inline in der DPR nicht funktioniert, könnte man für das Logger-Interface auch einen Wrapper-Record definieren, der die Aufrufe unter IFDEF an das Interface weiterreicht. Damit wird keine der inlined Record-Methoden aufgerufen, wenn das entsprechende IFDEF nicht zutrifft. Einziger etwas unschöner Nebeneffekt ist, daß eine nicht verwendete Variable T in Main angemeckert wird.
Bei meinen Versuchen, ein 'NOP' Logger Implementierung des Logger Interfaces mit leeren Prozeduren zu schreiben und sie mit inline zu 'optimieren' hatte ich die blauen Punkte bei den Aufrufern. Ich teste es daher noch mal mit diesem Beispiel (in Delphi 2009). Vielen Dank für die Anregungen!
Michael
Michael Justin
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 30. Jan 2016, 13:42
Wenn du einen Logger implementierst, dann musst du immer ganz schön viel Boilerplate-Code schreiben.

Da würde ich noch ein Interface mit Wrapper dazwischen schieben:
Delphi-Quellcode:
unit djLogWriter;

interface

uses
  System.SysUtils,
  djLogAPI;

type
  TLogLevel = ( llTrace, llDebug, llInfo, llWarn, llError );
  TLogLevels = set of TLogLevel;

type
  IWriteLog = interface
    procedure WriteMessage( const ALevel: TLogLevel; const AName, AMessage: string; const AException: Exception );
  end;

  TLogWriterWrapper = class( TInterfacedObject, ILogger )
  private { fields }
    FName : string;
    FWriter : IWriteLog;
    FLogFilter: TLogLevels;
    procedure SendToWriter( const ALevel: TLogLevel; const AMessage: string; const AException: Exception ); inline;
  private { ILogger }
    procedure Debug( const AMsg: string ); overload;
    procedure Debug( const AFormat: string; const AArgs: array of const ); overload;
    procedure Debug( const AMsg: string; const AException: Exception ); overload;

    procedure Error( const AMsg: string ); overload;
    procedure Error( const AFormat: string; const AArgs: array of const ); overload;
    procedure Error( const AMsg: string; const AException: Exception ); overload;

    procedure Info( const AMsg: string ); overload;
    procedure Info( const AFormat: string; const AArgs: array of const ); overload;
    procedure Info( const AMsg: string; const AException: Exception ); overload;

    procedure Warn( const AMsg: string ); overload;
    procedure Warn( const AFormat: string; const AArgs: array of const ); overload;
    procedure Warn( const AMsg: string; const AException: Exception ); overload;

    procedure Trace( const AMsg: string ); overload;
    procedure Trace( const AFormat: string; const AArgs: array of const ); overload;
    procedure Trace( const AMsg: string; const AException: Exception ); overload;

    function IsDebugEnabled: Boolean;
    function IsErrorEnabled: Boolean;
    function IsInfoEnabled: Boolean;
    function IsWarnEnabled: Boolean;
    function IsTraceEnabled: Boolean;

    function Name: string;
  public
    constructor Create( const AName: string; const AWriter: IWriteLog; const ALogFilter: TLogLevels );
  end;

implementation

{ TLogWriterWrapper }

constructor TLogWriterWrapper.Create( const AName: string; const AWriter: IWriteLog; const ALogFilter: TLogLevels );
begin
  inherited Create;
  FName := AName;
  FWriter := AWriter;
  FLogFilter := ALogFilter;
end;

procedure TLogWriterWrapper.Debug( const AMsg: string );
begin
  SendToWriter( llDebug, AMsg, nil );
end;

procedure TLogWriterWrapper.Debug( const AMsg: string; const AException: Exception );
begin
  SendToWriter( llDebug, AMsg, AException );
end;

procedure TLogWriterWrapper.Debug( const AFormat: string; const AArgs: array of const );
begin
  SendToWriter( llDebug, Format( AFormat, AArgs ), nil );
end;

procedure TLogWriterWrapper.Error( const AMsg: string );
begin
  SendToWriter( llError, AMsg, nil );
end;

procedure TLogWriterWrapper.Error( const AFormat: string; const AArgs: array of const );
begin
  SendToWriter( llError, Format( AFormat, AArgs ), nil );
end;

procedure TLogWriterWrapper.Error( const AMsg: string; const AException: Exception );
begin
  SendToWriter( llError, AMsg, AException );
end;

procedure TLogWriterWrapper.Info( const AFormat: string; const AArgs: array of const );
begin
  SendToWriter( llInfo, Format( AFormat, AArgs ), nil );
end;

procedure TLogWriterWrapper.Info( const AMsg: string );
begin
  SendToWriter( llInfo, AMsg, nil );
end;

procedure TLogWriterWrapper.Info( const AMsg: string; const AException: Exception );
begin
  SendToWriter( llInfo, AMsg, AException );
end;

function TLogWriterWrapper.IsDebugEnabled: Boolean;
begin
  Result := not( llDebug in FLogFilter );
end;

function TLogWriterWrapper.IsErrorEnabled: Boolean;
begin
  Result := not( llError in FLogFilter );
end;

function TLogWriterWrapper.IsInfoEnabled: Boolean;
begin
  Result := not( llInfo in FLogFilter );
end;

function TLogWriterWrapper.IsTraceEnabled: Boolean;
begin
  Result := not( llTrace in FLogFilter );
end;

function TLogWriterWrapper.IsWarnEnabled: Boolean;
begin
  Result := not( llWarn in FLogFilter );
end;

function TLogWriterWrapper.Name: string;
begin
  Result := FName;
end;

procedure TLogWriterWrapper.SendToWriter( const ALevel: TLogLevel; const AMessage: string; const AException: Exception );
begin
  if not( ALevel in FLogFilter )
  then
    FWriter.WriteMessage( ALevel, FName, AMessage, AException );
end;

procedure TLogWriterWrapper.Trace( const AMsg: string );
begin
  SendToWriter( llTrace, AMsg, nil );
end;

procedure TLogWriterWrapper.Trace( const AFormat: string; const AArgs: array of const );
begin
  SendToWriter( llTrace, Format( AFormat, AArgs ), nil );
end;

procedure TLogWriterWrapper.Trace( const AMsg: string; const AException: Exception );
begin
  SendToWriter( llTrace, AMsg, AException );
end;

procedure TLogWriterWrapper.Warn( const AMsg: string; const AException: Exception );
begin
  SendToWriter( llWarn, AMsg, AException );
end;

procedure TLogWriterWrapper.Warn( const AMsg: string );
begin
  SendToWriter( llWarn, AMsg, nil );
end;

procedure TLogWriterWrapper.Warn( const AFormat: string; const AArgs: array of const );
begin
  SendToWriter( llWarn, Format( AFormat, AArgs ), nil );
end;

end.
Mit einem Wrapper, kann man jetzt ganz kleine süße Log-Writer erstellen, die einfach nur IWriteLog implementieren.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.042 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#10

AW: Open Source "Logging Facade" für Pascal auf Github

  Alt 29. Jan 2016, 16:42
Geht das, evtl. mit Interfaces ?
Interfaces bringen nunmal ein virtuellen Methodenaufruf mit sich, darum kommst du nicht herum.
Einfach nen Nullobjekt dahinter hauen, und fertig.
Die Performancebeeinflussung dafür ist imo nur theoretischer Natur.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz