You are not logged in.
Pages: 1
Hello,
For some areas in the SQLite3 framework, it might be interesting to use some kind of logging framework, for example for
* collecting performance information
* writing generated SQL statements
* notifications about special events
* ...
(a logging framework could also be used by the other parts of the application)
This could be implemented using an existing open source logging library (if the licenses are compatible)
Cheers
Michael
Offline
At the application level, logging is made easy via the TSQLRecordLog record type.
At the framework level, logging could make a difference.
I've already some code dedicated to this task available. I'll merge it to the main trunk.
It's definitively a good idea.
Thanks for your interest!
Offline
At the application level, logging is made easy via the TSQLRecordLog record type
Hi ab,
Can you give me some hint or a few lines of sample code to get me started using TSQLRecordLog?
Can I store the logs to an external database, rather than the main database?
Thank you!
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
The best for a record-based log could be to use our TSynBigTable.
It will keep your main database small, and be very efficient.
The TSQLRecordLog stores the logs as JSON in the main database.
It's purpose was to store some logs associated to another record.
I'll post some sample code later.
Offline
Great advise! I'll check TSynBigTable!
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
Here is some sample code:
type
/// the table used for each log entry
TSQLRecordLogTestOneLog = class(TSQLRecord)
private
fStatus: integer;
fStatusMessage: RawUTF8;
fTime: TTimeLog;
published
/// Time of event (Int64 encoded)
property Time: TTimeLog read fTime write fTime;
/// log status, just an integer here (should be an enumeration in your
// program, to have direct caption on grids)
property Status: integer read fStatus;
/// status message (optional)
property StatusMessage: RawUTF8 read fStatusMessage;
end;
/// a table containing some fields, including a log list encoded as JSON
TSQLRecordLogTest = class(TSQLRecordLog)
private
fText: RawUTF8;
fStatusLog: RawUTF8;
protected
/// this entry is used during the logging
fOneLog: TSQLRecordLogTestOneLog;
public
/// release used memory
destructor Destroy; override;
/// add one entry to the internal logging status array
// - use LogTableJSON method to retrieve it as JSON, and save it into
// StatusLog property in the table
procedure AddLog(aStatus: Integer; const aMessage: RawUTF8);
/// retrieve the StatusLog field content, as a TSQLTable
function LogTable: TSQLTableJSON;
published
/// some record field
property Text: RawUTF8 read fText write fText;
/// status log, i.e. TSQLRecordLogTestOneLog table encoded as JSON
property StatusLog: RawUTF8 read fStatusLog write fStatusLog;
end;
{ TSQLRecordLogTest }
procedure TSQLRecordLogTest.AddLog(aStatus: Integer;
const aMessage: RawUTF8);
begin
if fOneLog=nil then
fOneLog := TSQLRecordLogTestOneLog.Create;
fOneLog.Time := Iso8601Now;
fOneLog.Status := aStatus;
fOneLog.StatusMessage := aMessage;
Log(fOneLog); // add this content as JSON-log row
end;
destructor TSQLRecordLogTest.Destroy;
begin
fOneLog.Free;
inherited;
end;
function TSQLRecordLogTest.LogTable: TSQLTableJSON;
begin
result := TSQLTableJSON.Create([TSQLPhDEventLog],'',fClientStatusLog);
result.IDColumnHide;
end;
Take a look at the comments to guess how it works.
In short: you create some logging records, appended in some JSON field which is stored in a table record.
Then you can get the logging list from the JSON field, with the LogTable method, the assign it to the UI Grid of the framework for direct display.
Offline
Thanks for the sample code! But I don't understand, what's the advantage of using TSQLTableJSON?
One more question, for some reasons, I can't use tbigtable but want to store the logs to a SQLITE DB instead. I'll use TSQLRestClientURINamedPipe server component, and I'm wondering if I can have multiple TSQLRestClientURINamedPipe instances - one for the main data while another for logs only, so that I can save my logs to a separate database. But I read the following line in the source code:
// - allows only one ExportServer*() by running process
Does it mean it's not possible? And I found this similar thread about TSQLite3HttpServer
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
From the client side, TSQLTableJSON will contain all logs records, decoded from its JSON field.
It can be used to populate a Grid to view all logs.
This grid is very fast, and will do most of the formating work for you, thanks to its link to the ORM properties:
http://synopse.info/forum/viewtopic.php?id=140
Offline
I got it!
And you might overlooked my new question - "is it possible to have multiple TSQLRestClientURINamedPipe instances in a single process?"
Thanks!
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
You can have only multipleTSQLRestServerNamedPipe per process, if you specify diverse ApplicationName parameter values to TSQLRestServer.ExportServerNamedPipe(), one per each TSQLRestServer you create.
For TSQLRestClientURINamedPipe, it only allow one concurrent access.
You could try to change the following code:
constructor TSQLRestClientURINamedPipe.Create(aModel: TSQLModel;
const ApplicationName: TFileName);
var Pipe: cardinal;
procedure CreatePipe;
begin
Pipe := CreateFile(pointer(fPipeName), GENERIC_READ or GENERIC_WRITE,
{$ifdef ANONYMOUSNAMEDPIPE}
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, SECURITY_SQOS_PRESENT or SECURITY_ANONYMOUS, 0);
{$else}
FILE_SHARE_READ or FILE_SHARE_WRITE, // this is added to allow sharing
@fPipeSecurityAttributes, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, 0);
{$endif}
end;
Only HTTP/1.1 allows multiple concurrent connections at once.
Offline
Hi ab,
Thanks for the info. I think I've come up with an alternative (maybe better) approach - The multiple clients send the logs to the single server via a RESTful JSON method on the server side, and in that method the log will in turn be stored into another database by via another TSQLRest object.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
For some areas in the SQLite3 framework, it might be interesting to use some kind of logging framework, for example for
* collecting performance information
* writing generated SQL statements
* notifications about special events
* ...
You had a dream... and it's now reality!
See http://synopse.info/forum/viewtopic.php?pid=1809#p1809
Offline
Pages: 1