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