uemep_logger.f90 Source File


Files dependent on this one

sourcefile~~uemep_logger.f90~~AfferentGraph sourcefile~uemep_logger.f90 uemep_logger.f90 sourcefile~uemep_configuration.f90 uemep_configuration.f90 sourcefile~uemep_configuration.f90->sourcefile~uemep_logger.f90 sourcefile~uemep_main.f90 uEMEP_main.f90 sourcefile~uemep_main.f90->sourcefile~uemep_logger.f90 sourcefile~uemep_main.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_command_line.f90 uEMEP_read_command_line.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_command_line.f90 sourcefile~uemep_auto_subgrid.f90 uEMEP_auto_subgrid.f90 sourcefile~uemep_main.f90->sourcefile~uemep_auto_subgrid.f90 sourcefile~uemep_calculate_exposure.f90 uEMEP_calculate_exposure.f90 sourcefile~uemep_main.f90->sourcefile~uemep_calculate_exposure.f90 sourcefile~uemep_chemistry_no2.f90 uEMEP_chemistry_NO2.f90 sourcefile~uemep_main.f90->sourcefile~uemep_chemistry_no2.f90 sourcefile~uemep_crossreference_grids.f90 uEMEP_crossreference_grids.f90 sourcefile~uemep_main.f90->sourcefile~uemep_crossreference_grids.f90 sourcefile~uemep_define_subgrid.f90 uEMEP_define_subgrid.f90 sourcefile~uemep_main.f90->sourcefile~uemep_define_subgrid.f90 sourcefile~uemep_grid_roads.f90 uEMEP_grid_roads.f90 sourcefile~uemep_main.f90->sourcefile~uemep_grid_roads.f90 sourcefile~uemep_read_agriculture_rivm_data.f90 uEMEP_read_agriculture_rivm_data.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_agriculture_rivm_data.f90 sourcefile~uemep_read_config.f90 uEMEP_read_config.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_config.f90 sourcefile~uemep_read_emep.f90 uEMEP_read_EMEP.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_emep.f90 sourcefile~uemep_read_industry_data.f90 uEMEP_read_industry_data.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_industry_data.f90 sourcefile~uemep_read_landuse_rivm_data.f90 uEMEP_read_landuse_rivm_data.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_landuse_rivm_data.f90 sourcefile~uemep_read_meteo_nc.f90 uEMEP_read_meteo_nc.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_meteo_nc.f90 sourcefile~uemep_read_receptor_data.f90 uEMEP_read_receptor_data.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_receptor_data.f90 sourcefile~uemep_read_roadlink_data_ascii.f90 uEMEP_read_roadlink_data_ascii.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_roadlink_data_ascii.f90 sourcefile~uemep_read_rwc_heating_data.f90 uEMEP_read_RWC_heating_data.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_rwc_heating_data.f90 sourcefile~uemep_read_shipping_asi_data.f90 uEMEP_read_shipping_asi_data.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_shipping_asi_data.f90 sourcefile~uemep_read_ssb_data.f90 uEMEP_read_SSB_data.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_ssb_data.f90 sourcefile~uemep_read_time_profiles.f90 uEMEP_read_time_profiles.f90 sourcefile~uemep_main.f90->sourcefile~uemep_read_time_profiles.f90 sourcefile~uemep_redistribute_data.f90 uEMEP_redistribute_data.f90 sourcefile~uemep_main.f90->sourcefile~uemep_redistribute_data.f90 sourcefile~uemep_save_emission_netcdf.f90 uEMEP_save_emission_netcdf.f90 sourcefile~uemep_main.f90->sourcefile~uemep_save_emission_netcdf.f90 sourcefile~uemep_save_netcdf_file.f90 uEMEP_save_netcdf_file.f90 sourcefile~uemep_main.f90->sourcefile~uemep_save_netcdf_file.f90 sourcefile~uemep_set_constants.f90 uEMEP_set_constants.f90 sourcefile~uemep_main.f90->sourcefile~uemep_set_constants.f90 sourcefile~uemep_set_emission_factors.f90 uEMEP_set_emission_factors.f90 sourcefile~uemep_main.f90->sourcefile~uemep_set_emission_factors.f90 sourcefile~uemep_set_filenames.f90 uEMEP_set_filenames.f90 sourcefile~uemep_main.f90->sourcefile~uemep_set_filenames.f90 sourcefile~uemep_set_subgrids.f90 uEMEP_set_subgrids.f90 sourcefile~uemep_main.f90->sourcefile~uemep_set_subgrids.f90 sourcefile~uemep_subgrid_deposition.f90 uEMEP_subgrid_deposition.f90 sourcefile~uemep_main.f90->sourcefile~uemep_subgrid_deposition.f90 sourcefile~uemep_subgrid_deposition_emep.f90 uEMEP_subgrid_deposition_EMEP.f90 sourcefile~uemep_main.f90->sourcefile~uemep_subgrid_deposition_emep.f90 sourcefile~uemep_subgrid_dispersion.f90 uEMEP_subgrid_dispersion.f90 sourcefile~uemep_main.f90->sourcefile~uemep_subgrid_dispersion.f90 sourcefile~uemep_subgrid_emep.f90 uEMEP_subgrid_EMEP.f90 sourcefile~uemep_main.f90->sourcefile~uemep_subgrid_emep.f90 sourcefile~uemep_subgrid_emission_emep.f90 uEMEP_subgrid_emission_EMEP.f90 sourcefile~uemep_main.f90->sourcefile~uemep_subgrid_emission_emep.f90 sourcefile~uemep_subgrid_meteo_emep.f90 uEMEP_subgrid_meteo_EMEP.f90 sourcefile~uemep_main.f90->sourcefile~uemep_subgrid_meteo_emep.f90 sourcefile~uemep_tiling_routines.f90 uEMEP_tiling_routines.f90 sourcefile~uemep_main.f90->sourcefile~uemep_tiling_routines.f90 sourcefile~uemep_read_command_line.f90->sourcefile~uemep_logger.f90 sourcefile~uemep_read_command_line.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_aggregate_proxy_emission_in_emep_grid.f90 uEMEP_aggregate_proxy_emission_in_EMEP_grid.f90 sourcefile~uemep_aggregate_proxy_emission_in_emep_grid.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_auto_subgrid.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_calculate_exposure.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_chemistry_no2.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_crossreference_grids.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_define_subgrid.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_grid_roads.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_agriculture_rivm_data.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_config.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_emep.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_industry_data.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_landuse_rivm_data.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_landuse_rivm_data.f90->sourcefile~uemep_crossreference_grids.f90 sourcefile~uemep_read_meteo_nc.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_meteo_nc.f90->sourcefile~uemep_read_config.f90 sourcefile~uemep_read_receptor_data.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_roadlink_data_ascii.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_rwc_heating_data.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_shipping_asi_data.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_ssb_data.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_read_time_profiles.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_redistribute_data.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_redistribute_data.f90->sourcefile~uemep_save_netcdf_file.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_grid_roads.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_read_agriculture_rivm_data.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_read_industry_data.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_read_meteo_nc.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_read_roadlink_data_ascii.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_read_rwc_heating_data.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_read_shipping_asi_data.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_read_time_profiles.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_save_netcdf_file.f90 sourcefile~uemep_save_emission_netcdf.f90->sourcefile~uemep_set_emission_factors.f90 sourcefile~uemep_save_netcdf_file.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_save_netcdf_file.f90->sourcefile~uemep_chemistry_no2.f90 sourcefile~uemep_set_constants.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_set_dispersion_params.f90 uEMEP_set_dispersion_params.f90 sourcefile~uemep_set_dispersion_params.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_set_emission_factors.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_set_filenames.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_set_subgrids.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_subgrid_deposition.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_subgrid_deposition.f90->sourcefile~uemep_set_dispersion_params.f90 sourcefile~uemep_subgrid_deposition_emep.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_subgrid_dispersion.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_subgrid_dispersion.f90->sourcefile~uemep_set_dispersion_params.f90 sourcefile~uemep_subgrid_emep.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_subgrid_emission_emep.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_subgrid_meteo_emep.f90->sourcefile~uemep_configuration.f90 sourcefile~uemep_tiling_routines.f90->sourcefile~uemep_configuration.f90

Source Code

module uemep_logger
    ! A simple logger module for uEMEP

    implicit none
    private

    public :: DEBUG, INFO, WARNING, ERROR
    public :: open_log_file, close_log_file, set_log_level, log_message, log_header
    public :: log_msg

    integer, parameter :: DEBUG = 1
    integer, parameter :: INFO = 2
    integer, parameter :: WARNING = 3
    integer, parameter :: ERROR = 4
    
    integer, save :: log_level = INFO
    character(len=256), save :: log_name
    logical, save :: file_opened = .false.
    integer :: log_unit
    character(len=1028) :: log_msg

    integer :: unit

contains

    subroutine open_log_file(logfile_name, io_err)
        !! Opens a new log file for writing
        character(len=*), intent(in) :: logfile_name
        integer, intent(inout), optional :: io_err

        ! Store unit and file name information in module
        log_name = trim(logfile_name)

        ! Open log file
        if (present(io_err)) then
            open(newunit=log_unit, file=log_name, status="replace", iostat=io_err)
        else
            open(newunit=log_unit, file=log_name, status="replace")
        end if
        file_opened = .true.
    end subroutine open_log_file

    subroutine close_log_file(io_err)
        integer, intent(inout), optional :: io_err
        !! Closes the log file
        if (file_opened) then
            if (present(io_err)) then
                close(log_unit, iostat=io_err)
            else
                close(log_unit)
            end if
            log_unit = -1
        end if
    end subroutine close_log_file

    subroutine set_log_level(level)
        !! Sets the log level
        !!
        !! The logger will write all message at or above this level
        integer, intent(in) :: level
        if (level >= DEBUG .and. level <= ERROR) then
            log_level = level
        else
            print *, "ERROR! Invalid log level: ", level
            stop 1
        end if
    end subroutine set_log_level

    subroutine log_header(message, level, upper_space, lower_space)
        !! Send a log header message to the log file
        !!
        !! Log levels: DEBUG, INFO, WARNING and ERROR        
        character(len=*), intent(in) :: message !! Message to log
        integer, intent(in) :: level !! Log level
        logical, intent(in), optional :: upper_space, lower_space

        ! Local variables
        logical :: u_space, l_space

        if (present(upper_space)) then
            u_space = upper_space
        else
            u_space = .true.
        end if

        if (present(lower_space)) then
            l_space = lower_space
        else
            l_space = .true.
        end if
        
        if (u_space) call log_message("", level)
        call log_message("================================================================", level)
        call log_message(message, level)
        call log_message("================================================================", level)
        if (l_space) call log_message("", level)
    end subroutine log_header

    subroutine log_message(message, level)
        !! Send a log message to the log file
        !!
        !! Log levels: DEBUG, INFO, WARNING and ERROR
        character(len=*), intent(in) :: message !! Message to log
        integer, intent(in) :: level !! Log level
        
        ! Local variables
        character(len=18) :: timestamp
        character(len=8) :: datestr
        character(len=10) :: timestr

        ! Get current date and time
        call date_and_time(date=datestr, time=timestr)
        timestamp = '[' // datestr // ' ' // timestr(1:6) // '] '

        if (level >= log_level) then
            select case(level)
            case(DEBUG)
                call write_log(timestamp // '[DEBUG] ' // message)
            case(INFO)
                call write_log(timestamp // '[INFO]  ' // message)
            case(WARNING)
                call write_log(timestamp // '[WARN]  ' // message)
            case(ERROR)
                call write_log(timestamp // '[ERROR] ' // message)
            case default
                print "(a)", "ERROR: Invalid log level: ", level
                stop 1
            end select
        end if
    end subroutine log_message

    subroutine write_log(message)
        !! Writes the message to the log file
        character(len=*), intent(in) :: message !! Message to log

        if (.not. file_opened) then
            print "(a)", "ERROR: No file has been opened for writing"
            stop 1
        end if

        write(log_unit, "(a)") trim(adjustl(message))
    end subroutine write_log

end module uemep_logger