libsim Versione 8.0.0

◆ l4f_log()

subroutine, public l4f_log ( integer(kind=c_int), intent(in) a_priority,
character(len=*), intent(in) a_format )

Emit log message without category with specific priority.

Fortran version that receives a Fortran character argument.

Parametri
[in]a_prioritypriority level
[in]a_formatmessage to emit

Definizione alla linea 838 del file log4fortran.F90.

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

Generated with Doxygen.