libsim Versione 8.0.0

◆ l4f_category_log_f()

subroutine l4f_category_log_f ( type(l4f_handle), intent(in) a_category,
integer(kind=c_int), intent(in) a_priority,
character(len=*), intent(in) a_format )
private

Emit log message for a category with specific priority.

Fortran version that receives a Fortran character argument.

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

Definizione alla linea 807 del file log4fortran.F90.

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