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