2016-10-19 10 views
0

В службе REST службы Datasnap (модуль ISAPI) Я хотел бы знать способ, который вы назвали. Я собираюсь использовать его в общей рутине для записи журналов при каждой ошибке/исключении, которая происходит.Как узнать метод, вызванный службой REST Datasnap

procedure WriteLog(Error: string); 
var Log, Service, LogFile: string; 
begin 
    Service := ExtractFileName(GetModuleName(HInstance)); 
    Service := Copy(Service, 1, Service.Length - 4); 
    if not TDirectory.Exists('C:\Logs') then TDirectory.CreateDirectory('C:\Logs'); 
    if not TDirectory.Exists('C:\Logs\' + Service) then TDirectory.CreateDirectory('C:\Logs\' + Service); 
    LogFile := 'C:\Logs\' + Service + '\' + FormatDateTime('yyyy-mm-dd_hh-nn-zzz', Now) + '.txt'; 

    Log := 'Call : ' + XXXXXX + sLineBreak; 
    Log := Log + 'User : ' + TDSSessionManager.GetThreadSession.GetData('User') + sLineBreak; 
    Log := Log + 'IP : ' + TDSSessionManager.GetThreadSession.GetData('RemoteIP') + sLineBreak; 
    Log := Log + 'Error : ' + sLineBreak + Error; 
    TFile.WriteAllText(LogFile, Log); 
end; 

Мне нужно заменить XXXXXX на название вызванного метода.

Эта информация доступна в WebModule службы в параметре Request для события WebModuleBeforeDispatch.

Но я не могу установить это значение в данных сеанса (поэтому он будет доступен для моей программы WriteLog), потому что в этот момент сеанса еще нет.

Этот код поднимает AV:

procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); 
begin 
    Response.SetCustomHeader('Access-Control-Allow-Origin','*'); 

    if Trim(Request.GetFieldByName('Access-Control-Request-Headers')) <> '' then begin 
    Response.SetCustomHeader('Access-Control-Allow-Headers', Request.GetFieldByName('Access-Control-Request-Headers')); 
    Handled := True; // I answer to CORS calls 
    end; 

    TDSSessionManager.GetThreadSession.PutData('MethodCalled', Request.PathInfo); 

    if FServerFunctionInvokerAction <> nil then 
    FServerFunctionInvokerAction.Enabled := AllowServerFunctionInvoker; 
end; 

На данный момент я установить переменную ThreadVar на WebModule держать это значение, поэтому она может быть доступна для обычной WriteLog.

Это работает, но глобальная переменная является очень уродливым решением, и, что более важно, она вызывает небольшую утечку памяти после каждого вызова.

Как вы думаете, что я могу сохранить это значение, чтобы я мог его прочитать, когда мне это нужно?

спасибо.

+1

Как и всем нам, вы можете просто вставить вызов WriteLog в каждый метод на вашем сервере. – nolaspeaker

ответ

1

Я думаю, что он доступен из EventObject.MethodAlias ​​в событии DSAuthenticationManagerUserAuthorize.