New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
logger.f90 in branches/2013/dev_rev4119_MERCATOR4_CONFMAN/NEMOGCM/TOOLS/SIREN/src – NEMO

source: branches/2013/dev_rev4119_MERCATOR4_CONFMAN/NEMOGCM/TOOLS/SIREN/src/logger.f90 @ 4213

Last change on this file since 4213 was 4213, checked in by cbricaud, 10 years ago

first draft of the CONFIGURATION MANAGER demonstrator

File size: 20.7 KB
Line 
1!----------------------------------------------------------------------
2! NEMO system team, System and Interface for oceanic RElocable Nesting
3!----------------------------------------------------------------------
4!
5! MODULE: logger
6!
7! DESCRIPTION:
8!> @brief This module create logger file and inform it depending
9!>  of verbosity choose between :
10!>    - trace : Most detailed information.
11!>    - debug : Detailed information on the flow through the system.
12!>    - info  : Interesting runtime events (startup/shutdown).
13!>    - warning: Use of deprecated APIs, poor use of API, 'almost' errors,
14!> other runtime situations that are undesirable or unexpected,
15!> but not necessarily "wrong".
16!>    - error : Other runtime errors or unexpected conditions.
17!>    - fatal : Severe errors that cause premature termination.<br />
18!>  default verbosity is warning
19!
20!> @details
21!>    If total number of error exceeded maximum number
22!>    authorized, program stop.
23!>
24!>    to open/create logger file:<br/>
25!>    CALL logger_open(cd_file, [cd_verbosity,] [id_loggerid,] [id_maxerror])
26!>       - cd_file is logger file name
27!>       - cd_verbosity is verbosity to be used (optional, default 'warning')
28!>       - id_loggerid is file id (optional, use only to flush)
29!>       - id_maxerror is the mximum number of error authorized before stop program (optional, default 5)
30!>
31!>    to close logger file:<br/>
32!>    CALL logger_close()
33!>
34!>    to write header in logger file:<br/>
35!>    CALL logger_header()
36!>
37!>    to write footer in logger file:<br/>
38!>    CALL logger_footer()
39!>
40!>    to flushing output:<br/>
41!>    CALL logger_flush()
42!>
43!>    to write TRACE message in logger file:<br/>
44!>    CALL logger_trace(cd_msg)
45!>       - cd_msg is TRACE message
46!>
47!>    to write DEBUG message in logger file:<br/>
48!>    CALL logger_debug(cd_msg)
49!>       - cd_msg is DEBUG message
50!>
51!>    to write INFO message in logger file:<br/>
52!>    CALL logger_info(cd_msg)
53!>       - cd_msg is INFO message
54!>
55!>    to write WARNING message in logger file:<br/>
56!>    CALL logger_warn(cd_msg)
57!>       - cd_msg is WARNING message
58!>
59!>    to write ERROR message in logger file:<br/>
60!>    CALL logger_error(cd_msg)
61!>       - cd_msg is ERROR message
62!>
63!>    to write FATAL message in logger file:<br/>
64!>    CALL logger_fatal(cd_msg)
65!>       - cd_msg is FATAL message
66!>
67!>  Examples :<br />
68!>   CALL logger_open('loggerfile.txt','info')
69!>
70!>   CALL logger_header()<br />
71!>   CALL logger_info('une petite info')<br />
72!>   CALL logger_debug('une info de debug')<br />
73!>   CALL logger_warn('une info de warning')<br />
74!>   CALL logger_error('une info d erreur')<br />
75!>   CALL logger_footer()<br />
76!>   CALL logger_close()<br />
77!>
78!> !--------------------------------------------------------------------<br />
79!>   CALL logger_open('loggerfile.txt')
80!>
81!>   CALL logger_header()<br />
82!>   CALL logger_info('une petite info')<br />
83!>   CALL logger_debug('une info de debug')<br />
84!>   CALL logger_warn('une info de warning')<br />
85!>   CALL logger_error('une info d erreur')<br />
86!>   CALL logger_footer()<br />
87!>   CALL logger_close()<br />
88!
89!> @author
90!> J.Paul
91! REVISION HISTORY:
92!> @date Nov, 2013- Initial Version
93!>
94!> @note Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
95!>
96!> @todo
97!> - verifier flush remet pas compteur error à zero
98!----------------------------------------------------------------------
99MODULE logger
100   USE kind                            ! F90 kind parameter
101   USE fct                             ! basic useful function
102   IMPLICIT NONE
103   PRIVATE
104   ! NOTE_avoid_public_variables_if_possible
105
106   ! type and variable
107   !PUBLIC :: TLOGGER            ! logger structure
108
109   ! function and subroutine
110   PUBLIC :: logger_open        ! create a log file with given verbosity
111   PUBLIC :: logger_close       ! close log file
112   PUBLIC :: logger_flush       ! flushing output
113   PUBLIC :: logger_header      ! write header on log file
114   PUBLIC :: logger_footer      ! write footer on log file
115   PUBLIC :: logger_trace       ! write trace    message in log file
116   PUBLIC :: logger_debug       ! write debug    message in log file
117   PUBLIC :: logger_info        ! write info     message in log file
118   PUBLIC :: logger_warn        ! write warning  message in log file
119   PUBLIC :: logger_error       ! write error    message in log file
120   PUBLIC :: logger_fatal       ! write fatal    message in log file, and stop
121
122   PRIVATE :: logger__write     ! cut message to get maximum of 80 character by line in log file
123
124   !> @struct TLOG
125   TYPE TLOGGER
126      INTEGER(i4)       :: i_id = 0                 !< log file id
127      CHARACTER(LEN=lc) :: c_name                   !< log file name
128      CHARACTER(LEN=lc) :: c_verbosity = "warning"  !< verbosity choose
129      CHARACTER(LEN=lc) :: c_verb = ""              !< table of "verbosities" to used
130      INTEGER(i4)       :: i_nerror   = 0           !< number of error
131      INTEGER(i4)       :: i_nfatal   = 0           !< number of fatal error
132      INTEGER(i4)       :: i_maxerror = 5           !< maximum number of error before stoping program
133   END TYPE TLOGGER   
134
135   !  module variable
136   INTEGER(i4), PARAMETER :: im_nverbosity=6     !< number of log level
137   CHARACTER(len=*), DIMENSION(im_nverbosity), PARAMETER :: cm_verbosity= & !< verbosity table
138   &               (/ 'trace   ',&
139   &                  'debug   ',&
140   &                  'info    ',& 
141   &                  'warning ',&
142   &                  'error   ',&
143   &                  'fatal   '/)
144
145   TYPE(TLOGGER), SAVE :: tm_logger      !< logger structure
146                                                 
147CONTAINS
148   !-------------------------------------------------------------------
149   !> @brief This subroutine create a log file with given verbosity.
150   !>
151   !> @author J.Paul
152   !> - Nov, 2013- Initial Version
153   !
154   !> @param[in] cd_file : log file name
155   !> @param[in] cd_verbosity : log file verbosity
156   !> @param[in] id_logid : log file id (use to flush)
157   !> @param[in] id_maxerror : maximum number of error
158   !-------------------------------------------------------------------
159   ! @code
160   SUBROUTINE logger_open(cd_file, cd_verbosity, id_logid, id_maxerror)
161      IMPLICIT NONE
162      ! Argument
163      CHARACTER(len=*), INTENT(IN) :: cd_file                ! log file name
164      CHARACTER(len=*), INTENT(IN), OPTIONAL :: cd_verbosity ! log file verbosity
165      INTEGER(i4),      INTENT(IN), OPTIONAL :: id_logid     ! log file id
166      INTEGER(i4),      INTENT(IN), OPTIONAL :: id_maxerror  ! log max error
167
168      ! local variable
169      INTEGER(i4) :: il_status
170
171      ! loop
172      INTEGER(i4) :: ji
173      !----------------------------------------------------------------
174      ! get id if not already define
175      IF( PRESENT(id_logid) )THEN
176         tm_logger%i_id=id_logid
177      ELSE
178         tm_logger%i_id=fct_getunit()
179      ENDIF
180
181      ! open log file
182      OPEN( tm_logger%i_id, &
183      &     STATUS="unknown",    &
184      &     FILE=TRIM(ADJUSTL(cd_file)),  &
185      &     ACTION="write",      &
186      &     POSITION="append",   &
187      &     IOSTAT=il_status)
188      CALL fct_err(il_status)
189
190      ! keep filename
191      tm_logger%c_name=TRIM(ADJUSTL(cd_file))
192
193      ! if present, change verbosity value
194      IF( PRESENT(cd_verbosity) )THEN
195         tm_logger%c_verbosity=TRIM(ADJUSTL(cd_verbosity))
196      ENDIF
197
198      ! compute "tab" of verbosity to be used
199      IF( TRIM(ADJUSTL(tm_logger%c_verb)) == "" )THEN
200         DO ji=im_nverbosity,1,-1
201            tm_logger%c_verb = &
202            &  TRIM(tm_logger%c_verb)//" "//TRIM(ADJUSTL(cm_verbosity(ji)))
203            IF( TRIM(tm_logger%c_verbosity) == TRIM(cm_verbosity(ji)) )THEN
204               EXIT
205            ENDIF
206         ENDDO
207      ENDIF
208
209      IF( PRESENT(id_maxerror) )THEN
210         tm_logger%i_maxerror=id_maxerror
211      ENDIF
212
213   END SUBROUTINE logger_open
214   ! @endcode
215   !-------------------------------------------------------------------
216   !> @brief This subroutine close a log file.
217   !>
218   !> @author J.Paul
219   !> - Nov, 2013- Initial Version
220   !
221   !-------------------------------------------------------------------
222   ! @code
223   SUBROUTINE logger_close()
224      IMPLICIT NONE
225      ! local variable
226      INTEGER(i4) :: il_status
227      !----------------------------------------------------------------
228      IF( tm_logger%i_id /= 0 )THEN
229         CLOSE( tm_logger%i_id, &
230         &      IOSTAT=il_status)     
231         CALL fct_err(il_status)
232      ELSE
233          CALL logger_open('logger.log')
234          CALL logger_header()
235          CALL logger_fatal('you must have create logger to use logger_close')
236      ENDIF
237
238   END SUBROUTINE logger_close
239   ! @endcode
240   !-------------------------------------------------------------------
241   !> @brief This subroutine flushing output into log file.
242   !>
243   !> @author J.Paul
244   !> - Nov, 2013- Initial Version
245   !
246   !-------------------------------------------------------------------
247   ! @code
248   SUBROUTINE logger_flush()
249      IMPLICIT NONE
250      !----------------------------------------------------------------
251      IF( tm_logger%i_id /= 0 )THEN
252         CALL logger_close()
253         CALL logger_open( tm_logger%c_name, tm_logger%c_verbosity, tm_logger%i_id, &
254         &              tm_logger%i_maxerror )     
255      ELSE
256          CALL logger_open('logger.log')
257          CALL logger_header()
258          CALL logger_fatal('you must have create logger to use logger_flush')
259      ENDIF
260
261   END SUBROUTINE logger_flush
262   ! @endcode   
263   !-------------------------------------------------------------------
264   !> @brief This subroutine write header on log file.
265   !>
266   !> @author J.Paul
267   !> - Nov, 2013- Initial Version
268   !
269   !-------------------------------------------------------------------
270   ! @code
271   RECURSIVE SUBROUTINE logger_header()
272      IMPLICIT NONE
273      ! local variable
274      INTEGER(i4) :: il_status
275      !----------------------------------------------------------------
276      IF( tm_logger%i_id /= 0 )THEN
277         WRITE( tm_logger%i_id,    &
278            &   FMT='(a/a/a)',     &
279            &   IOSTAT=il_status ) &
280            &   "--------------------------------------------------", &
281            &   "INIT     : log start with verbosity "//&
282            &   TRIM(tm_logger%c_verbosity), &
283            &   "--------------------------------------------------"
284         CALL fct_err(il_status)
285      ELSE
286          CALL logger_open('logger.log')
287          CALL logger_header()
288          CALL logger_fatal('you must have create logger to use logger_header')
289      ENDIF
290
291   END SUBROUTINE logger_header
292   ! @endcode   
293   !-------------------------------------------------------------------
294   !> @brief This subroutine write footer on log file.
295   !>
296   !> @author J.Paul
297   !> - Nov, 2013- Initial Version
298   !
299   !-------------------------------------------------------------------
300   ! @code
301   SUBROUTINE logger_footer()
302      IMPLICIT NONE
303      ! local variable
304      INTEGER(i4) :: il_status
305      !----------------------------------------------------------------
306      IF( tm_logger%i_id /= 0 )THEN
307         WRITE( tm_logger%i_id,    &
308            &   FMT='(a/a/a/a/a)',     &
309            &   IOSTAT=il_status ) &
310            &   "--------------------------------------------------",&
311            &   "END      : log ended ",                             &
312            &   "END      : "//TRIM(fct_str(tm_logger%i_nerror))//   &
313            &   " ERROR detected ",                                  &
314            &   "END      : "//TRIM(fct_str(tm_logger%i_nfatal))//   &
315            &   " FATAL detected ",                                  &
316            &   "--------------------------------------------------"
317         CALL fct_err(il_status)
318      ELSE
319          CALL logger_open('logger.log')
320          CALL logger_header()
321          CALL logger_fatal('you must have create logger to use logger_footer')
322      ENDIF
323   END SUBROUTINE logger_footer
324   ! @endcode   
325   !-------------------------------------------------------------------
326   !> @brief This subroutine write trace message on log file.
327   !>
328   !> @author J.Paul
329   !> - Nov, 2013- Initial Version
330   !
331   !> @param[in] cd_msg : message to write
332   !> @param[in] ld_flush : flushing ouput
333   !
334   !-------------------------------------------------------------------
335   ! @code
336   SUBROUTINE logger_trace(cd_msg, ld_flush)
337      IMPLICIT NONE
338      ! Argument
339      CHARACTER(LEN=*), INTENT(IN)  :: cd_msg
340      LOGICAL,          INTENT(IN), OPTIONAL :: ld_flush
341      !----------------------------------------------------------------
342      IF( tm_logger%i_id /= 0 )THEN
343         IF( INDEX(TRIM(tm_logger%c_verb),'trace')/=0 )THEN
344
345            CALL logger__write("TRACE   :",cd_msg)
346
347            IF( PRESENT(ld_flush) )THEN
348               IF( ld_flush )THEN
349                  CALL logger_flush()
350               ENDIF
351            ENDIF     
352         ENDIF
353      ELSE
354          CALL logger_open('logger.log')
355          CALL logger_header()
356          CALL logger_fatal('you must have create logger to use logger_trace')
357      ENDIF
358   END SUBROUTINE logger_trace
359   ! @endcode   
360   !-------------------------------------------------------------------
361   !> @brief This subroutine write debug message on log file.
362   !>
363   !> @author J.Paul
364   !> - Nov, 2013- Initial Version
365   !
366   !> @param[in] cd_msg : message to write
367   !> @param[in] ld_flush : flushing ouput
368   !
369   !-------------------------------------------------------------------
370   ! @code
371   SUBROUTINE logger_debug(cd_msg, ld_flush)
372      IMPLICIT NONE
373      ! Argument
374      CHARACTER(LEN=*), INTENT(IN)  :: cd_msg
375      LOGICAL,          INTENT(IN), OPTIONAL :: ld_flush
376      !----------------------------------------------------------------
377      IF( tm_logger%i_id /= 0 )THEN
378         IF( INDEX(TRIM(tm_logger%c_verb),'debug')/=0 )THEN
379
380            CALL logger__write("DEBUG   :",cd_msg)
381
382            IF( PRESENT(ld_flush) )THEN
383               IF( ld_flush )THEN
384                  CALL logger_flush()
385               ENDIF
386            ENDIF     
387         ENDIF
388      ELSE
389          CALL logger_open('logger.log')
390          CALL logger_header()
391          CALL logger_fatal('you must have create logger to use logger_debug')
392      ENDIF
393   END SUBROUTINE logger_debug
394   ! @endcode   
395   !-------------------------------------------------------------------
396   !> @brief This subroutine write info message on log file.
397   !>
398   !> @author J.Paul
399   !> - Nov, 2013- Initial Version
400   !
401   !> @param[in] cd_msg : message to write
402   !> @param[in] ld_flush : flushing ouput
403   !
404   !-------------------------------------------------------------------
405   ! @code
406   SUBROUTINE logger_info(cd_msg, ld_flush)
407      IMPLICIT NONE
408      ! Argument
409      CHARACTER(LEN=*), INTENT(IN)  :: cd_msg
410      LOGICAL,          INTENT(IN), OPTIONAL :: ld_flush
411      !----------------------------------------------------------------
412      IF( tm_logger%i_id /= 0 )THEN
413         IF( INDEX(TRIM(tm_logger%c_verb),'info')/=0 )THEN
414
415            CALL logger__write("INFO    :",cd_msg)
416
417            IF( PRESENT(ld_flush) )THEN
418               IF( ld_flush )THEN
419                  CALL logger_flush()
420               ENDIF
421            ENDIF     
422         ENDIF
423      ELSE
424          CALL logger_open('logger.log')
425          CALL logger_header()
426          CALL logger_fatal('you must have create logger to use logger_info')
427      ENDIF
428   END SUBROUTINE logger_info
429   ! @endcode   
430   !-------------------------------------------------------------------
431   !> @brief This subroutine write warning message on log file.
432   !>
433   !> @author J.Paul
434   !> - Nov, 2013- Initial Version
435   !
436   !> @param[in] cd_msg : message to write
437   !> @param[in] ld_flush : flushing ouput
438   !
439   !-------------------------------------------------------------------
440   ! @code
441   SUBROUTINE logger_warn(cd_msg, ld_flush)
442      IMPLICIT NONE
443      ! Argument
444      CHARACTER(LEN=*), INTENT(IN)  :: cd_msg
445      LOGICAL,          INTENT(IN), OPTIONAL :: ld_flush
446      !----------------------------------------------------------------
447      IF( tm_logger%i_id /= 0 )THEN
448         IF( INDEX(TRIM(tm_logger%c_verb),'warn')/=0 )THEN
449
450            CALL logger__write("WARNING :",cd_msg)
451
452            IF( PRESENT(ld_flush) )THEN
453               IF( ld_flush )THEN
454                  CALL logger_flush()
455               ENDIF
456            ENDIF     
457         ENDIF
458      ELSE
459          CALL logger_open('logger.log')
460          CALL logger_header()
461          CALL logger_fatal('you must have create logger to use logger_warn')
462      ENDIF
463   END SUBROUTINE logger_warn
464   ! @endcode   
465   !-------------------------------------------------------------------
466   !> @brief This subroutine write error message on log file.
467   !>
468   !> @author J.Paul
469   !> - Nov, 2013- Initial Version
470   !
471   !> @param[in] cd_msg : message to write
472   !> @param[in] ld_flush : flushing ouput
473   !
474   !-------------------------------------------------------------------
475   ! @code
476   SUBROUTINE logger_error(cd_msg, ld_flush)
477      IMPLICIT NONE
478      ! Argument
479      CHARACTER(LEN=*), INTENT(IN)  :: cd_msg
480      LOGICAL,          INTENT(IN), OPTIONAL :: ld_flush
481
482      ! local variable
483      CHARACTER(LEN=lc) :: cl_nerror
484      !----------------------------------------------------------------
485      IF( tm_logger%i_id /= 0 )THEN
486         ! increment the error number
487         tm_logger%i_nerror=tm_logger%i_nerror+1
488
489         IF( INDEX(TRIM(tm_logger%c_verb),'error')/=0 )THEN
490
491            CALL logger__write("ERROR   :",cd_msg)
492
493            IF( PRESENT(ld_flush) )THEN
494               IF( ld_flush )THEN
495                  CALL logger_flush()
496               ENDIF
497            ENDIF     
498         ENDIF
499
500         IF( tm_logger%i_nerror >= tm_logger%i_maxerror )THEN
501            WRITE(cl_nerror,*) tm_logger%i_maxerror
502            CALL logger_fatal(&
503            &  'Error count reached limit of '//TRIM(ADJUSTL(cl_nerror)) )
504         ENDIF
505      ELSE
506          CALL logger_open('logger.log')
507          CALL logger_header()
508          CALL logger_fatal('you must have create logger to use logger_error')
509      ENDIF
510
511   END SUBROUTINE logger_error
512   ! @endcode   
513   !-------------------------------------------------------------------
514   !> @brief This subroutine write fatal error message on log file,
515   !> close log file and stop process.
516   !>
517   !> @author J.Paul
518   !> - Nov, 2013- Initial Version
519   !
520   !> @param[in] cd_msg : message to write
521   !
522   !-------------------------------------------------------------------
523   ! @code
524   RECURSIVE SUBROUTINE logger_fatal(cd_msg)
525      IMPLICIT NONE
526      ! Argument
527      CHARACTER(LEN=*),           INTENT(IN) :: cd_msg
528      !----------------------------------------------------------------
529      IF( tm_logger%i_id /= 0 )THEN
530         IF( INDEX(TRIM(tm_logger%c_verb),'fatal')/=0 )THEN
531            ! increment the error number
532            tm_logger%i_nfatal=tm_logger%i_nfatal+1
533
534            CALL logger__write("FATAL   :",cd_msg)
535
536            CALL logger_footer()
537            CALL logger_close()
538
539            STOP
540         ENDIF
541      ELSE
542          CALL logger_open('logger.log')
543          CALL logger_header()
544          CALL logger_fatal('you must have create logger to use logger_fatal')
545      ENDIF
546   END SUBROUTINE logger_fatal
547   ! @endcode   
548   !-------------------------------------------------------------------
549   !> @brief This subroutine cut message to get maximum of 80 character
550   !> by line in log file.
551   !>
552   !> @author J.Paul
553   !> - Nov, 2013- Initial Version
554   !
555   !> @param[in] cd_verb : verbosity of the message to write
556   !> @param[in] cd_msg : message to write
557   !-------------------------------------------------------------------
558   ! @code
559   SUBROUTINE logger__write(cd_verb, cd_msg)
560      IMPLICIT NONE
561      ! Argument
562      CHARACTER(LEN=*),           INTENT(IN) :: cd_verb
563      CHARACTER(LEN=*),           INTENT(IN) :: cd_msg
564
565      ! local variable
566      INTEGER(i4)       :: il_status
567      INTEGER(i4)       :: il_verb
568      INTEGER(i4)       :: il_msg
569      CHARACTER(LEN=lc) :: cl_verb
570      CHARACTER(LEN=lc) :: cl_msg
571      CHARACTER(LEN=lc) :: cl_tmp
572
573      !----------------------------------------------------------------
574      cl_verb=TRIM(ADJUSTL(cd_verb))
575      cl_msg=TRIM(ADJUSTL(cd_msg))
576
577      il_verb=LEN_TRIM(cl_verb)
578      il_msg=LEN_TRIM(cl_msg)
579      DO WHILE( il_verb + il_msg > 78 )
580         cl_tmp=TRIM(cl_verb)//' '//TRIM(cl_msg(1:78-il_verb))
581
582         WRITE( tm_logger%i_id,  &
583         &      FMT=*,           &
584         &      IOSTAT=il_status &
585         &      ) TRIM(cl_tmp)
586         CALL fct_err(il_status)
587
588
589         cl_msg=cl_msg(78-il_verb+1:il_msg)
590         cl_verb="        :"
591
592         il_msg=LEN_TRIM(cl_msg)
593
594      ENDDO
595
596      cl_tmp=TRIM(cl_verb)//' '//TRIM(cl_msg)
597      WRITE( tm_logger%i_id,  &
598      &      FMT=*,           &
599      &      IOSTAT=il_status &
600      &      ) TRIM(cl_tmp)
601      CALL fct_err(il_status)
602
603   END SUBROUTINE logger__write
604   ! @endcode   
605END MODULE logger
606
Note: See TracBrowser for help on using the repository browser.