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