Что нового
  • Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Web application error logging made easy

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,071
Баллы
155
Возраст
51
TMS Software Delphi  Components

As software developer, don't you always wish to collect as much information as possible when an error occurs in your application?
Just like with native Windows applications, where exception loggers exist for a long time, also for web applications this is a desirable tool to have. And for sure, in the web world, such solutions also exist for quite some time. And it doesn't stop with logging errors, it might be useful to log all kinds of other information on a central server database.

Cook your own logger!

With this example, we show you how unbelievable easy it became to log errors in a

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

application or other things on a central server. For this case, we take advantage of our newest offering:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. StellarDS.io offers you central data access as a service. It saves you from learning how to write, deploy and secure a backend server. It is up & running already and in a matter of minutes, you define the data you need and start using it! In this example, we'll guide you step by step how you can do this.

Setup your StellarDS.io account

TMS Software Delphi  Components


So, signup for the

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

and after doing this, you can start setting up your project. Your default project has a project ID you will use later. For this logging example, we need just one table, so go ahead and under Tables, create the table Log. In this table, we will create 5 fields, but nothing prevents you from adcding more if you want to log more information. Note the ID of the table, as we'll need it later in the logger class.

The fields we will use are:

App : string fieldthe name of the application for which we want to log
User : string fieldthe name of the user using this app
TimeStamp : DateTime fieldthe time at which something is logged
Message : Blob fielda blob field used to store a large amount of text. This will hold the exception information
Navigator : Blob fieldalso a blob field to store details about the browser in which the error happened
In the StellarDS.io admin panel this looks like:

TMS Software Delphi  Components


Next, we'll need to create a means of access to the StellarDS.io service from our web app. Two methods exist:

OAuth based authentication & authorization for accessThis means, a user needs to login first with credentials before obtaining an access token with which the StellarDS.io API can be access.
Fixed access token This is preferably domain locked to prevent this token can be used for other purposes.
In this example, for reasons of simplicity, we will use a fixed access token. So, go ahead and create an access token. For debugging purposes, lock this to the domain

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

but remember that when you're about to deploy your app, to change this to a token locked to your domain on which you deploy the app.

There isn't more to it. Our StellarDS.io account is ready to go.

Create the logger class

We are going to create a class that is fast & easy to use to log information on the StellarDS.io service. The class has the following public interface:


TStellarDSLogger = class(TPersistent)
public
constructor Create(ProjectID: string; TableID: integer; AccessToken: string);
procedure Log(App, User, Msg: string); {$IFDEF PAS2JS} async; {$ENDIF}
end;


So, you create the an instance of this logger class, pass via the constructor the access token, the project ID and the table ID. Other than this, there is the Log() method that will send the logging data, consisting of App name, User name and Message to the service.

Class implementation

It will be interesting to have a look at the actual implementation of this class. We are taking advantage here of the classes already created to access StellarDS.io that are included in TMS WEB Core. This includes the classes TStellarDataStore, TStellarDataStoreTable, TStellarDataStoreEntity. By means of these classes, you do not need to bother about figuring out the StellarDS.io REST API but you can use these logically architected classes. So, we will create the TStellarDataStore class mapping on our StellarDS.io project and one TStellarDataStoreTable mapping on our StellarDS.io table.

The constructor of our logger class therefore looks like:

constructor TStellarDSLogger.Create(ProjectID: string; TableID: integer;
AccessToken: string);
begin
FDS := TStellarDataStore.Create(nil);
FDS.AccessToken := AccessToken;
FDS.ProjectID := ProjectID;
FDS.Tables.Add;
FDT := FDS.Tables[0];
FDT.TableID := TableID.ToString;
end;
Then there is the actual log method that looks like:

procedure TStellarDSLogger.Log(App, User, Msg: string);
var
de: TStellarDataStoreEntity;
res: string;
begin
if FDT.Fields.Count = 0 then
begin
TAwait.ExecP<boolean>(FDT.GetFields);
end;

de := FDT.Entities.Add;
de.Value['App'] := App;
de.Value['User'] := User;
de.Value['TimeStamp'] := DateTimeToRFC3339(Now);

res := TAwait.ExecP<string>(de.Insert);
if (res<> '') then
begin
TAwait.ExecP<boolean>(de.WriteBlob('Message', Msg, res));
TAwait.ExecP<boolean>(de.WriteBlob('Navigator', TJSJSON.stringify(GetNavigatorInfo), res));
end;
end;

What we see here is:

1) When our table was first created, it doesn't get the field information from the service by default, so, when we log the first time and this field information was not retrieved yet, we call FDT.GetFields. Notice that this uses a TAwait construct as, like with all HTTP requests in a web application, it is executed asynchronously.

2) We add an entity (i.e. a record) to the table and set its values. As eventually the information from the entity is sent as JSON text object to the server, we set the values as strings for each of the fields we use. Note here the use of the method DateTimeToRFC3339(). This method is used to convert to the current time to a string adhering the expected

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.

Blob fields are for performance reasons never stored in one call with regular fields on the server. Intead, when a new record is created in the table, the blob fields get a unique URL value and by means of a HTTP GET or POST, blob data is retrieved or written to the field. This is what you see after the asynchronous insert of the new record, where two blob field values are written. One for the log message and one for the browser information. To collect the browser information, we wrote a function GetNavigatorInfo that returns a whole lot of browser info as JSON object. In order to send it to the StellarDS.io service via a HTTP request, we convert this JSON object to a string with the function TJSJSON.stringify().

Start using the logger

In our application, we create an instance of the logger class with:

LLogger := TStellarDSLogger.Create(cProjectID, cTableID, ACCESS_TOKEN);

Then, we attach an event handler to the Application.OnError event:

Application.OnError := AppError;

with the implementation:

procedure TForm1.AppError(Sender: TObject; AError: TApplicationError; var Handled: boolean);
begin
LLogger.Log('My app', 'My user', TJSJSON.stringify(AError));
end;

The Application.OnError event handler is called with the error information stored in an object AError: TApplicationError and also this object is writting as string to the Message blob field.

Viewing logs

From any other machine or app, we can easily make a log viewer. To make our lives easier, for the viewer, we will use the TWebStellarDataStoreClientDataSet. We connect this dataset to our Log table and this dataset, we can easily show in a TWebDBGrid by connecting it to the dataset via a TWebDataSource (all identical to the way we do databinding in a VCL application).


WebDataSource1.DataSet := WebStellarDataStoreClientDataset1;
WebDBGrid1.DataSource := WebDataSource1;
WebStellarDataStoreClientDataset1.AccessToken := ACCESS_TOKEN;
WebStellarDataStoreClientDataset1.TableID := cTableId;
WebStellarDataStoreClientDataset1.ProjectID := cProjectID;
WebStellarDataStoreClientDataset1.Active := true;

This will fill the TWebDBGrid with the information that is logged. To show the log for a specific user, app or date range, we can use WebStellarDataStoreClientDataset1.TableWhereQuery to set the filter.

For the attentive reader, you'll realize that we won't see the message & navigator information stored in the blob right-away. Indeed, for performance reasons, it needs to be retriebed on demand. To visualize the exception message for example in a TWebMemo control, following code can be used:

var
s: string;
begin
s := TAwait.ExecP<string>(WebStellarDataStoreClientDataset1.ReadBlobAsText('Navigator'));
WebMemo1.Lines.Text := s;
end;


The result in the browser looks like this:

TMS Software Delphi  Components


Get started!
Make sure you are on the latest

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

version (beta is available at this moment for all active TMS WEB Core or TMS ALL-ACCESS users) and download the project

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. Create the account at

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

and a few minutes you'll have a web application that has loggin on board!


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх