------------------------------------------------------------------------------
-- 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;