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