source: dynamico_lmdz/simple_physics/phyparam/physics/logging.F90 @ 4236

Last change on this file since 4236 was 4236, checked in by dubos, 5 years ago

simple_physics : some Python bindings

File size: 4.9 KB
Line 
1MODULE logging
2
3  ! see also use_logging.h
4  ! macro LOGBUF accumulates log output into logging_buffer
5  IMPLICIT NONE
6  SAVE
7  PRIVATE
8
9  INTERFACE  ! Explicit interfaces for plugins
10     ! Plugin that typically prints all lines in the loggin buffer 'buf' and prepends tags (log level, timestamp, ...)
11     SUBROUTINE plugin(lev, taglen, tag, buflen, bufsize, buf) BIND(C)
12       USE, INTRINSIC :: iso_c_binding, ONLY : c_char, c_null_char, c_int
13       INTEGER(c_int), INTENT(IN), VALUE :: lev, taglen, buflen, bufsize
14       CHARACTER(KIND=c_char), INTENT(IN) :: tag(taglen), buf(buflen, bufsize)
15     END SUBROUTINE plugin
16
17     ! Plugin that writes into string 'line' information about the gridpoint of index 'index'
18     SUBROUTINE plugin_log_gridpoint(index, line_len, line) BIND(C)
19       USE, INTRINSIC :: iso_c_binding, ONLY : c_char, c_null_char, c_int
20       INTEGER(c_int), INTENT(IN), VALUE :: index, line_len ! index of gridpoint, LEN(line)
21       CHARACTER(KIND=c_char), INTENT(OUT) :: line(line_len)
22     END SUBROUTINE plugin_log_gridpoint
23
24  END INTERFACE
25
26
27  ! This module provides a default implementations of plugins but the top-level driver is welcome to override them.
28  ! Note F2003/F2008: pgfortran (F2003) accepts to initialize pointers only to NULL()
29  ! => plugins are initialzed to NULL() and set to default values in flush_log and log_gridpoint
30#ifndef XCODEML
31  ! Note F2003/F2008: XCodeML cannot parse procedure pointers
32  PUBLIC :: flush_plugin, log_gridpoint_plugin
33  PROCEDURE(plugin), POINTER :: flush_plugin => NULL()
34  PROCEDURE(plugin_log_gridpoint), POINTER :: log_gridpoint_plugin => NULL()
35#endif
36
37  INTEGER, PARAMETER :: linesize=10000, logging_bufsize=100
38  CHARACTER(linesize) :: logging_buf(logging_bufsize)
39
40  INTEGER :: logging_lineno=0
41
42  ! messages with a log level > max_log_level are not printed
43  INTEGER, PARAMETER, PUBLIC :: log_level_fatal=1, log_level_error=2, log_level_warn=3, log_level_info=4, log_level_dbg=5
44  INTEGER, PUBLIC :: max_log_level = log_level_info
45  CHARACTER(3), DIMENSION(log_level_dbg), PUBLIC :: dbtag = (/ 'FAT', 'ERR', 'WRN', 'INF', 'DBG' /)
46
47  PUBLIC :: logging_buf, logging_bufsize, logging_lineno, flush_log, log_gridpoint, &
48       missing_plugin
49
50CONTAINS
51
52  SUBROUTINE set_plugins(flush_plugin_c) BIND(C, name='phyparam_set_plugins_logging')
53    !$cython header void phyparam_set_plugins_logging(void *);
54    USE, INTRINSIC :: ISO_C_BINDING
55    TYPE(C_FUNPTR), INTENT(IN), VALUE :: flush_plugin_c
56    CALL C_F_PROCPOINTER(flush_plugin_c, flush_plugin)
57  END SUBROUTINE set_plugins
58
59  SUBROUTINE missing_plugin(name, mod)
60    CHARACTER(*), INTENT(IN) :: name, mod
61    WRITE(logging_buf(1),*) 'WARNING : plugin ', name, ' not provided by the driver program'
62    WRITE(logging_buf(2),*) '        see ', mod
63    logging_lineno=2
64    CALL flush_log(log_level_warn, 'missing_plugin')
65  END SUBROUTINE missing_plugin
66
67  !-------------------------------------------------------------------------------------------------
68
69  SUBROUTINE flush_log(lev,tag)
70    INTEGER, INTENT(IN) :: lev
71    CHARACTER(*), INTENT(IN) :: tag
72#ifndef XCODEML
73    IF(.NOT.ASSOCIATED(flush_plugin)) THEN
74       flush_plugin => default_flush_plugin
75       WRITE(*,*) 'WARNING : plugin flush_plugin not provided by the driver program'
76       WRITE(*,*) '        see logging.F90'
77    END IF
78    IF(logging_lineno>0 .AND. lev<=max_log_level) &
79         CALL flush_plugin(lev, LEN(tag), TRIM(tag), linesize, logging_lineno, logging_buf)
80    logging_lineno=0
81#endif
82  END SUBROUTINE flush_log
83
84  SUBROUTINE default_flush_plugin(lev, taglen, tag, buflen, bufsize, buf)
85    USE, INTRINSIC :: iso_c_binding, ONLY : c_char, c_null_char, c_int
86    INTEGER(c_int), INTENT(IN), VALUE :: lev, taglen, buflen, bufsize
87    CHARACTER(KIND=c_char), INTENT(IN) :: tag(taglen), buf(buflen, bufsize)
88    CHARACTER(100) :: prefix
89    CHARACTER(buflen+1) :: line
90    INTEGER :: i
91    WRITE(prefix,*) '[', dbtag(lev), ' ', tag, ']'
92    DO i=1, bufsize
93       WRITE(line,*) buf(:,i)
94       WRITE(*,*) TRIM(prefix), TRIM(line)
95    END DO
96  END SUBROUTINE default_flush_plugin
97
98  !-------------------------------------------------------------------------------------------------
99
100  SUBROUTINE log_gridpoint(index)
101    INTEGER, INTENT(IN) :: index
102    logging_lineno = logging_lineno+1
103#ifndef XCODEML
104    IF(.NOT.ASSOCIATED(log_gridpoint_plugin)) THEN
105       log_gridpoint_plugin => default_log_gridpoint
106       WRITE(*,*) 'WARNING : plugin log_gridpoint_plugin not provided by the driver program'
107       WRITE(*,*) '        see logging.F90'
108    END IF
109    CALL log_gridpoint_plugin(index, linesize, logging_buf(logging_lineno))
110#endif
111  END SUBROUTINE log_gridpoint
112
113  SUBROUTINE default_log_gridpoint(index, line_len, line)
114    USE, INTRINSIC :: iso_c_binding, ONLY : c_char, c_null_char, c_int
115    INTEGER(c_int), INTENT(IN), VALUE :: index, line_len ! index of gridpoint, LEN(line)
116    CHARACTER(KIND=c_char), INTENT(OUT) :: line(line_len)
117    line=' '
118  END SUBROUTINE default_log_gridpoint
119
120END MODULE logging
Note: See TracBrowser for help on using the repository browser.