------------------------------------------------------------------------------ -- Ada Web Server -- -- -- -- Copyright (C) 2000-2014, AdaCore -- -- -- -- This library is free software; you can redistribute it and/or modify -- -- it under terms of the GNU General Public License as published by the -- -- Free Software Foundation; either version 3, or (at your option) any -- -- later version. This library is distributed in the hope that it will be -- -- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- As a special exception under Section 7 of GPL version 3, you are -- -- granted additional permissions described in the GCC Runtime Library -- -- Exception, version 3.1, as published by the Free Software Foundation. -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- . -- -- -- -- As a special exception, if other files instantiate generics from this -- -- unit, or you link this unit with other files to produce an executable, -- -- this unit does not by itself cause the resulting executable to be -- -- covered by the GNU General Public License. This exception does not -- -- however invalidate any other reasons why the executable file might be -- -- covered by the GNU Public License. -- ------------------------------------------------------------------------------ -- This package handle the logging facility for AWS. The log file is named -- '-Y-M-D.log' and is written by default in the directory where -- the server is launched, see configuration file. -- -- Note that this package is used internally by AWS to log server requests -- but it can also be used by users to handle application's log. -- -- This package is thread safe. with AWS.Containers.String_Vectors; with AWS.Headers; with AWS.Messages; with AWS.Response; with AWS.Status; private with Ada.Containers.Indefinite_Ordered_Maps; private with Ada.Finalization; private with Ada.Strings.Unbounded; private with Ada.Text_IO; private with AWS.Utils; package AWS.Log is type Object is limited private; -- A log object. It must be activated by calling Start below type Callback is access procedure (Message : String); -- Access to a procedure that handles AWS access and/or error log data. -- If the access and/or error logs are started with a Callback procedure -- set, then AWS will no longer handle writing the log data to file, nor -- will it rotate or split the data. In short : If you set a Callback, it's -- up to you to handle these things. -- The raw log data generated by AWS is simply handed verbatim to the -- Callback procedure. type Split_Mode is (None, Each_Run, Daily, Monthly); -- It specifies when to create a new log file. -- None : all log info gets accumulated into the same file. -- Each_Run : a new log file is created each time the server is started. -- Daily : a new log file is created each day. -- Monthly : a new log file is created each month. type Fields_Table is private; -- Type to keep record for Extended Log File Format Empty_Fields_Table : constant Fields_Table; Not_Specified : constant String; procedure Start (Log : in out Object; Split : Split_Mode := None; Size_Limit : Natural := 0; File_Directory : String := Not_Specified; Filename_Prefix : String := Not_Specified; Auto_Flush : Boolean := False); -- Activate server's activity logging. Split indicate the way the log file -- should be created. If Size_Limit more than zero and size of log file -- become more than Size_Limit, log file would be splitted. Filename_Prefix -- is the log filename prefix. If it is not specified the default prefix is -- the program name. Set Auto_Flush to True if you want every write to the -- log to be flushed (not buffered). Auto_Flush should be set to True only -- for logs with few entries per second as the flush has a performance -- penalty. procedure Start (Log : in out Object; Writer : Callback; Name : String); -- Activate server's activity logging and send all log data to Callback. -- When the logging object is started with a Callback no splitting or size -- limits are imposed on the logging data. This will all have to be handled -- in the Callback. -- When a log is started with a Callback, all log data is passed verbatim -- to the Callback. -- The Name String is returned when the Filename function is called. This -- serves no other function than to label the Callback procedure. procedure Register_Field (Log : in out Object; Id : String); -- Register field to be written into extended log format procedure Set_Field (Log : Object; Data : in out Fields_Table; Id, Value : String); -- Set field value into the extended log record. Data could be used only -- in one task and with one log file. Different tasks could write own Data -- using the Write routine with Fields_Table parameter type. procedure Set_Header_Fields (Log : Object; Data : in out Fields_Table; Prefix : String; Header : AWS.Headers.List); -- Set header fields into extended log record. -- Name of the header fields would be (). -- Prefix should be "cs" - Client to Server or "sc" - Server to Client. procedure Write (Log : in out Object; Data : in out Fields_Table); -- Write extended format record to log file and prepare record for the next -- data. It is not allowed to use same Fields_Table with different extended -- logs. procedure Write (Log : in out Object; Connect_Stat : Status.Data; Answer : Response.Data); -- Write log info if activated (i.e. Start routine above has been called) procedure Write (Log : in out Object; Connect_Stat : Status.Data; Status_Code : Messages.Status_Code; Content_Length : Response.Content_Length_Type); -- Write log info if activated (i.e. Start routine above has been called). -- This version separated the Content_Length from Status.Data, this is -- required for example in the case of a user defined stream content. See -- AWS.Resources.Stream. procedure Write (Log : in out Object; Connect_Stat : Status.Data; Data : String); -- Write user's log info if activated. (i.e. Start routine above has been -- called). procedure Write (Log : in out Object; Data : String); -- Write Data into the log file. This Data is unstructured, only a time -- tag prefix is prepended to Data. This routine is designed to be used -- for user's info in error log file. procedure Flush (Log : in out Object); -- Flush the data to the Log file, for be able to see last logged -- messages. -- If a Callback procedure is used to handle the log data, then calling -- Flush does nothing. procedure Stop (Log : in out Object); -- Stop logging activity function Is_Active (Log : Object) return Boolean; -- Returns True if Log is activated function Filename (Log : Object) return String; -- Returns current log filename or the empty string if the log is not -- activated. -- If a Callback is used to handle the log, then the name given in the -- Start procedure is returned. See the Start procedure for starting logs -- with a Callback. function Mode (Log : Object) return Split_Mode; -- Returns the split mode. None will be returned if log is not activated or -- a Callback procedure is used to handle the log data. private use Ada; use Ada.Strings.Unbounded; package Strings_Positive is new Ada.Containers.Indefinite_Ordered_Maps (String, Positive); package SV renames AWS.Containers.String_Vectors; type Fields_Table is record Values : SV.Vector; end record; Empty_Fields_Table : constant Fields_Table := (Values => SV.Empty_Vector); Not_Specified : constant String := ""; type Object is new Ada.Finalization.Limited_Controlled with record File : Text_IO.File_Type; Writer : Callback := null; Writer_Name : Unbounded_String := Null_Unbounded_String; Stop_Has_Been_Called : Boolean := False; Extended_Fields : Strings_Positive.Map; Header_Written : Boolean; File_Directory : Unbounded_String; Filename_Prefix : Unbounded_String; Split : Split_Mode := None; Size_Limit : Natural := 0; Current_Tag : Positive; Semaphore : Utils.Semaphore; Auto_Flush : Boolean; end record; overriding procedure Finalize (Log : in out Object); end AWS.Log;