|
libsim Versione 8.0.0
|
◆ l4f_category_get()
Initialize a logging category. This is the Fortran legacy version that receives a Fortran character argument and returns an integer.
Definizione alla linea 763 del file log4fortran.F90. 764! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
765! authors:
766! Davide Cesari <dcesari@arpa.emr.it>
767! Paolo Patruno <ppatruno@arpa.emr.it>
768
769! This program is free software; you can redistribute it and/or
770! modify it under the terms of the GNU General Public License as
771! published by the Free Software Foundation; either version 2 of
772! the License, or (at your option) any later version.
773
774! This program is distributed in the hope that it will be useful,
775! but WITHOUT ANY WARRANTY; without even the implied warranty of
776! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
777! GNU General Public License for more details.
778
779! You should have received a copy of the GNU General Public License
780! along with this program. If not, see <http://www.gnu.org/licenses/>.
781#include "config.h"
782
783!> \defgroup log4fortran Libsim package, log4fortran library.
784!! Fortran interface to a basic set of log4c library for performing
785!! logging within a program.
786
787!>\brief classe per la gestione del logging
788!!
789!!Questo modulo permette una semplice, ma potente gestione della messagistica.
790!!E' utile sia in fase di debug che di monitoraggio utente.
791!!
792!!Questo modulo fornisce funzionalità simili, ma non identiche a
793!!seconda che siano disponibili in fase di compilazione le librerie
794!!log4c e cnf.
795!!
796!!There are three fundamental types of object in Log4C: categories,
797!!appenders and layouts. You can think of these objects as
798!!corresponding to the what, where and how of the logging system:
799!!categories describe what sub-system the message relates to,
800!!appenders determine where the message goes and layouts determine how
801!!the message is formatted.
802!!
803!!First, you have to figure out what kind of categories you
804!!want. Maybe you want one logger for GUI code and another one for
805!!memory management and a third one for user access
806!!logging. Okay. That's fine. Me, I like to have a separate logger for
807!!each class or data structure. I've already gone to the trouble of
808!!breaking my code down into such categories. Why not just use those?
809!!Feel free to set it up any way you like. Just don't make the mistake
810!!of using message severity as your categories. That's what the
811!!priority is all about.
812!!
813!! La gestione di appenders e layouts viene demandata in toto al file
814!! di configurazione di log4c (vedere apposita documentazione
815!! http://log4c.cvs.sourceforge.net/\*checkout\*/log4c/log4c/doc/Log4C-DevelopersGuide.odt )
816!!
817!!log4fortran by default can log messages with some standard priority levels:
818!!
819!!Use debug to write debugging messages which should not be printed
820!!when the application is in production.
821!!
822!!Use info for messages similar to the "verbose" mode of many
823!!applications.
824!!
825!!Use warn for warning messages which are logged to some log but the
826!!application is able to carry on without a problem.
827!!
828!!Use error for application error messages which are also logged to
829!!some log but, still, the application can hobble along. Such as when
830!!some administrator-supplied configuration parameter is incorrect and
831!!you fall back to using some hard-coded default value.
832!!
833!!Use fatal for critical messages, after logging of which the
834!!application quits abnormally.
835!!
836!!Configuration syntax:
837!!
838!!The log4crc configuration file uses an XML syntax. The root element
839!!is <log4c> and it can be used to control the configuration file
840!!version interface with the attribute "version". The following 4
841!!elements are supported: <config>, <category>, <appender> and
842!!<layout>.
843!!
844!! The <config> element controls the global log4c
845!! configuration. It has 3 sub elements. The <nocleanup> flag
846!! inhibits the log4c destructors routines. The <bufsize> element
847!! sets the buffer size used to format log4c_logging_event_t
848!! objects. If is set to 0, the allocation is dynamic (the <debug>
849!! element is currently unused).
850!!
851!! The <category> element has 3 possible attributes: the category
852!! "name", the category "priority" and the category
853!! "appender". Future versions will handle multple appenders per
854!! category.
855!!
856!! The <appender> element has 3 possible attributes: the appender
857!! "name", the appender "type", and the appender "layout".
858!!
859!! The <layout> element has 2 possible attributes: the layout
860!! "name" and the layout "type".
861!!
862!!
863!!This initial version of the log4c configuration file syntax is quite
864!!different from log4j. XML seemed the best choice to keep the log4j
865!!configuration power in a C API. Environment variables
866!!
867!! LOG4C_RCPATH holds the path to the main log4crc configuration file
868!! LOG4C_PRIORITY holds the "root" category priority
869!! LOG4C_APPENDER holds the "root" category appender
870!!
871!!
872!!Programma esempio \include log4fortran.f90
873!!Here's one sample log4crc configuration file \include log4crc
874!!
875!!\ingroup log4fortran
877USE iso_c_binding
878IMPLICIT NONE
879
880INTEGER(kind=c_int),PARAMETER :: L4F_FATAL = 000 !< standard priority
881INTEGER(kind=c_int),PARAMETER :: L4F_ALERT = 100 !< standard priority
882INTEGER(kind=c_int),PARAMETER :: L4F_CRIT = 200 !< standard priority
883INTEGER(kind=c_int),PARAMETER :: L4F_ERROR = 300 !< standard priority
884INTEGER(kind=c_int),PARAMETER :: L4F_WARN = 400 !< standard priority
885INTEGER(kind=c_int),PARAMETER :: L4F_NOTICE = 500 !< standard priority
886INTEGER(kind=c_int),PARAMETER :: L4F_INFO = 600 !< standard priority
887INTEGER(kind=c_int),PARAMETER :: L4F_DEBUG = 700 !< standard priority
888INTEGER(kind=c_int),PARAMETER :: L4F_TRACE = 800 !< standard priority
889INTEGER(kind=c_int),PARAMETER :: L4F_NOTSET = 900 !< standard priority
890INTEGER(kind=c_int),PARAMETER :: L4F_UNKNOWN = 1000 !< standard priority
891
892!> Default priority value. It is used only when compiled without log4c
893!! since the configuration file is ignored, but it is better to define
894!! it all the time.
895INTEGER(kind=c_int),PUBLIC :: l4f_priority=l4f_notice
896
897#ifdef HAVE_LIBLOG4C
898
899!> l4f handle. This type defines an opaque handle
900!! to a l4f category (mapped to a log4c category),
901!! it has to be initialised with the l4f_category_get_handle method.
902TYPE,BIND(C) :: l4f_handle
903 PRIVATE
904 TYPE(c_ptr) :: ptr = c_null_ptr
906
907
908TYPE(l4f_handle),SAVE :: l4f_global_default
909
910#undef ARRAYOF_ORIGEQ
911#undef ARRAYOF_ORIGTYPE
912#undef ARRAYOF_TYPE
913#define ARRAYOF_ORIGTYPE TYPE(l4f_handle)
914#define ARRAYOF_TYPE arrayof_l4f_handle
915#include "arrayof_pre_nodoc.F90"
916
917TYPE(arrayof_l4f_handle) :: l4f_global_ptr
918
919!> Global log4fortran constructor. It can be called by Fortran.
920INTERFACE
922 IMPORT
923 INTEGER(kind=c_int) :: l4f_init
925END INTERFACE
926
927! Internal C interface not to be used by user Fortran code
928INTERFACE
929 FUNCTION l4f_category_get_c(a_name) bind(C,name='log4c_category_get')
930 IMPORT
931 CHARACTER(kind=c_char),INTENT(in) :: a_name(*) !< category name
932 TYPE(l4f_handle) :: l4f_category_get_c
933 END FUNCTION l4f_category_get_c
934END INTERFACE
935
936! Internal C interface not to be used by user Fortran code
937! this function has been disabled because after deleting a category
938! the following log4c_fini fails with a double free, we must
939! understand the log4c docs
940INTERFACE
941 SUBROUTINE l4f_category_delete_c(a_category) bind(C,name='log4c_category_delete')
942 IMPORT
943 TYPE(l4f_handle),VALUE :: a_category !< category as C native pointer
944 END SUBROUTINE l4f_category_delete_c
945END INTERFACE
946
947!! Delete a logging category. It can receive a l4f_handle pointer or a
948!! legacy integer value.
949INTERFACE l4f_category_delete
950 MODULE PROCEDURE l4f_category_delete_legacy, l4f_category_delete_f
951END INTERFACE
952
953! Internal C interface not to be used by user Fortran code
954INTERFACE
955 SUBROUTINE l4f_category_log_c(a_category, a_priority, a_format) bind(C,name='log4c_category_log_c')
956 IMPORT
957 TYPE(l4f_handle),VALUE :: a_category !< category
958 INTEGER(kind=c_int),VALUE :: a_priority !< priority level
959! TYPE(c_ptr),VALUE :: locinfo !< not used
960 CHARACTER(kind=c_char),INTENT(in) :: a_format(*) !< message to emit
961 ! TYPE(c_ptr),VALUE :: a_args
962 END SUBROUTINE l4f_category_log_c
963END INTERFACE
964
965!> Emit log message for a category with specific priority.
966!! It can receive a l4f_handle or a legacy integer value.
968 MODULE PROCEDURE l4f_category_log_f, l4f_category_log_legacy
970
971!> Return true if the corresponding category handle exists.
973 MODULE PROCEDURE l4f_category_exist_f, l4f_category_exist_legacy
975
976!> Global log4fortran destructor. It can be called by Fortran.
977INTERFACE
979 IMPORT
980 INTEGER(kind=c_int) :: l4f_fini
982END INTERFACE
983
984!>Ritorna un messaggio caratteristico delle priorità standard
985!interface
986!CHARACTER(len=12) FUNCTION l4f_msg(a_priority)
987!integer,intent(in):: a_priority !< category name
988!end function l4f_msg
989!end interface
990
991#else
992
993CHARACTER(len=510),PRIVATE:: dummy_a_name
994
995!> l4f handle. Dummy handle.
997 PRIVATE
998 INTEGER :: ptr = 0
1000
1001#endif
1002
1003PRIVATE
1004PUBLIC l4f_fatal, l4f_alert, l4f_crit, l4f_error, l4f_warn, l4f_notice, &
1005 l4f_info, l4f_debug, l4f_trace, l4f_notset, l4f_unknown
1006PUBLIC l4f_handle, l4f_init, l4f_category_get_handle, l4f_category_get, l4f_category_delete, l4f_category_log, &
1008PUBLIC l4f_launcher
1009
1010CONTAINS
1011
1012!> Routine specifica per il SIM. Cattura le variabili di ambiente
1013!! LOG4_APPLICATION_NAME,LOG4_APPLICATION_ID e compone il nome univoco
1014!! per il logging. Se le variabili di ambiente non sono impostate
1015!! ritorna un nome definito dal nome del processo e da un timestamp.
1016SUBROUTINE l4f_launcher(a_name, a_name_force, a_name_append)
1017CHARACTER(len=*),INTENT(out) :: a_name !< nome univoco per logging
1018CHARACTER(len=*),INTENT(in),OPTIONAL :: a_name_force !< forza il valore di a_name
1019CHARACTER(len=*),INTENT(in),OPTIONAL :: a_name_append !< valore da appendere a a_name
1020
1021INTEGER :: tarray(8)
1022CHARACTER(len=255) :: LOG4_APPLICATION_NAME,LOG4_APPLICATION_ID,arg
1023CHARACTER(len=255),SAVE :: a_name_save=""
1024
1025IF (PRESENT(a_name_force))THEN
1026 a_name=a_name_force
1027ELSE IF (a_name_save /= "")THEN
1028 a_name=a_name_save
1029ELSE
1030
1031 CALL date_and_time(values=tarray)
1032 CALL getarg(0, arg)
1033 CALL getenv("LOG4_APPLICATION_NAME", log4_application_name)
1034 CALL getenv("LOG4_APPLICATION_ID", log4_application_id)
1035
1036 IF (log4_application_name == "" .AND. log4_application_id == "") THEN
1037 WRITE(a_name,"(a,a,8i5,a)")trim(arg),"[",tarray,"]"
1038 ELSE
1039 a_name = trim(log4_application_name)//"["//trim(log4_application_id)//"]"
1040 END IF
1041
1042END IF
1043
1044a_name_save=a_name
1045
1046IF (PRESENT(a_name_append)) THEN
1047 a_name=trim(a_name)//"."//trim(a_name_append)
1048END IF
1049
1050END SUBROUTINE l4f_launcher
1051
1052#ifndef HAVE_LIBLOG4C
1053! define dummy function to replace log4c interface
1054
1055!> log4fortran global constructor
1057CHARACTER(len=10) :: priority
1058INTEGER :: iostat
1059
1060CALL getenv("LOG4C_PRIORITY",priority)
1061IF (priority=="") THEN
1062 l4f_priority = l4f_notice
1063ELSE
1064 READ(priority,*,iostat=iostat)l4f_priority
1065END IF
1066
1067IF (iostat /= 0) THEN
1068 l4f_priority = l4f_notice
1069END IF
1070
1071l4f_init = 0
1072
1074
1075
1076!>Initialize a logging category.
1077FUNCTION l4f_category_get(a_name) RESULT(handle)
1078CHARACTER(len=*),INTENT(in) :: a_name !< category name
1079
1080TYPE(l4f_handle) :: handle
1081
1082handle%ptr = 1
1083dummy_a_name = a_name
1084
1085END FUNCTION l4f_category_get
1086
1087
1088!>Delete a logging category.
1089SUBROUTINE l4f_category_delete(a_category)
1090TYPE(l4f_handle),INTENT(in) :: a_category !< category
1091
1092a_category%ptr = 0
1093dummy_a_name = ""
1094
1095END SUBROUTINE l4f_category_delete
1096
1097
1098!> Emit log message for a category with specific priority
1100TYPE(l4f_handle),INTENT(in) :: a_category !< category
1101INTEGER,INTENT(in):: a_priority !< priority level
1102CHARACTER(len=*),INTENT(in):: a_format !< message to emit
1103
1104IF (a_category%ptr == 1 .AND. a_priority <= l4f_priority) THEN
1105 WRITE(*,*)"[dummy] ",l4f_msg(a_priority),trim(dummy_a_name)," - ",trim(a_format)
1106ENDIF
1107
1109
1110
1111!> Emit log message without category with specific priority
1112SUBROUTINE l4f_log(a_priority,a_format)
1113INTEGER,INTENT(in):: a_priority !< priority level
1114CHARACTER(len=*),INTENT(in):: a_format !< message to emit
1115
1116IF (a_priority <= l4f_priority) THEN
1117 WRITE(*,*)"[_default] ",l4f_msg(a_priority),trim(dummy_a_name)," - ",trim(a_format)
1118ENDIF
1119
1120END SUBROUTINE l4f_log
1121
1122
1123!> Return True if category exist
1125TYPE(l4f_handle),INTENT(in) :: a_category !< category
1126
1127l4f_category_exist = a_category%ptr == 1
1128
1130
1131
1132!>log4fortran destructors
1134
1135l4f_fini= 0
1136
1138
1139!>Ritorna un messaggio caratteristico delle priorità standard
1140CHARACTER(len=12) FUNCTION l4f_msg(a_priority)
1141INTEGER,INTENT(in):: a_priority !< priority level
1142
1143write(l4f_msg,*)a_priority
1144
1145if (a_priority == l4f_fatal) l4f_msg="FATAL"
1146if (a_priority == l4f_alert) l4f_msg="ALERT"
1147if (a_priority == l4f_crit) l4f_msg="CRIT"
1148if (a_priority == l4f_error) l4f_msg="ERROR"
1149if (a_priority == l4f_warn) l4f_msg="WARN"
1150if (a_priority == l4f_notice) l4f_msg="NOTICE"
1151if (a_priority == l4f_info) l4f_msg="INFO"
1152if (a_priority == l4f_debug) l4f_msg="DEBUG"
1153if (a_priority == l4f_trace) l4f_msg="TRACE"
1154if (a_priority == l4f_notset) l4f_msg="NOTSET"
1155if (a_priority == l4f_unknown) l4f_msg="UNKNOWN"
1156
1157END FUNCTION l4f_msg
1158
1159#else
1160
1161#include "arrayof_post_nodoc.F90"
1162
1163!> Initialize a logging category. This is the
1164!! Fortran legacy version that receives a Fortran character argument
1165!! and returns an integer.
1166FUNCTION l4f_category_get(a_name) RESULT(handle)
1167CHARACTER(kind=c_char,len=*),INTENT(in) :: a_name !< category name
1168INTEGER :: handle
1169
1170handle = append(l4f_global_ptr, l4f_category_get_c(trim(a_name)//char(0)))
1171
1172END FUNCTION l4f_category_get
1173
1174
1175!> Initialize a logging category. This is the
1176!! Fortran version that receives a Fortran character argument
1177!! and returns a typed handle.
1178FUNCTION l4f_category_get_handle(a_name) RESULT(handle)
1179CHARACTER(kind=c_char,len=*),INTENT(in) :: a_name !< category name
1180TYPE(l4f_handle) :: handle
1181
1182handle = l4f_category_get_c(trim(a_name)//char(0))
1183
1184END FUNCTION l4f_category_get_handle
1185
1186
1187!> Delete a logging category. Legacy version with an integer argument.
1188SUBROUTINE l4f_category_delete_legacy(a_category)
1189INTEGER,INTENT(in) :: a_category !< category as an integer
1190
1191IF (a_category <= 0 .OR. a_category > l4f_global_ptr%arraysize) RETURN
1192CALL remove(l4f_global_ptr, pos=a_category)
1193
1194END SUBROUTINE l4f_category_delete_legacy
1195
1196
1197!> Delete a logging category. No-op version with a typed handle.
1198SUBROUTINE l4f_category_delete_f(a_category)
1199TYPE(l4f_handle),INTENT(inout) :: a_category !< category as C native pointer
1200
1201! hee the C function should be called, see comment above
1202! CALL l4f_category_delete_c(a_category)
1203a_category%ptr = c_null_ptr
1204
1205END SUBROUTINE l4f_category_delete_f
1206
1207
1208!> Emit log message for a category with specific priority.
1209!! Fortran version that receives a Fortran character argument.
1210SUBROUTINE l4f_category_log_f(a_category, a_priority, a_format)
1211TYPE(l4f_handle),INTENT(in) :: a_category !< category
1212INTEGER(kind=c_int),INTENT(in) :: a_priority !< priority level
1213CHARACTER(len=*),INTENT(in) :: a_format !< message to emit
1214
1215CALL l4f_category_log_c(a_category, a_priority, trim(a_format)//char(0))
1216
1217END SUBROUTINE l4f_category_log_f
1218
1219
1220!> Emit log message for a category with specific priority.
1221!! Legacy Fortran version that receives an integer instead of a C
1222!! pointer and a Fortran character argument.
1223SUBROUTINE l4f_category_log_legacy(a_category, a_priority, a_format)
1224INTEGER(kind=c_int),INTENT(in) :: a_category !< category
1225INTEGER(kind=c_int),INTENT(in) :: a_priority !< priority level
1226CHARACTER(len=*),INTENT(in) :: a_format !< message to emit
1227
1228CALL l4f_category_log_c(l4f_global_ptr%array(a_category), l4f_warn, &
1229 'You are using the legacy log4fortran interface!'//char(0))
1230CALL l4f_category_log_c(l4f_global_ptr%array(a_category), l4f_warn, &
1231 'Please, upgrade your code by defining category as `TYPE(l4f_handle)`'//char(0))
1232CALL l4f_category_log_c(l4f_global_ptr%array(a_category), l4f_warn, &
1233 'and replacing `l4f_category_get` with `l4f_category_get_handle`'//char(0))
1234CALL l4f_category_log_c(l4f_global_ptr%array(a_category), a_priority, trim(a_format)//char(0))
1235
1236END SUBROUTINE l4f_category_log_legacy
1237
1238
1239!> Emit log message without category with specific priority.
1240!! Fortran version that receives a Fortran character argument.
1241SUBROUTINE l4f_log(a_priority, a_format)
1242INTEGER(kind=c_int),INTENT(in) :: a_priority !< priority level
1243CHARACTER(len=*),INTENT(in) :: a_format !< message to emit
1244
1245INTEGER :: i
1246
1248 i = l4f_init()
1249 l4f_global_default = l4f_category_get_handle('_default')
1250ENDIF
1252
1253END SUBROUTINE l4f_log
1254
1255
1256!> Return true if the corresponding category handle exists
1257!! (is associated with a category).
1258FUNCTION l4f_category_exist_f(a_category) RESULT(exist)
1259TYPE(l4f_handle),INTENT(in) :: a_category !< category
1260LOGICAL :: exist
1261
1262exist = c_associated(a_category%ptr)
1263
1264END FUNCTION l4f_category_exist_f
1265
1266!> Return true if the corresponding category handle exists
1267!! (is associated with a category).
1268!! Legacy Fortran version that receives an integer instead of a C
1269!! pointer.
1270FUNCTION l4f_category_exist_legacy(a_category) RESULT(exist)
1271INTEGER,INTENT(in):: a_category !< category
1272LOGICAL :: exist
1273
1274IF (a_category <= 0 .OR. a_category > l4f_global_ptr%arraysize) THEN
1275 exist = .false.
1276ELSE
1277 exist = l4f_category_exist(l4f_global_ptr%array(a_category))
1278ENDIF
1279
1280END FUNCTION l4f_category_exist_legacy
1281
1282#endif
1283
Return true if the corresponding category handle exists. Definition log4fortran.F90:466 Emit log message for a category with specific priority. Definition log4fortran.F90:461 |