• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 15445734801

04 Jun 2025 03:00PM UTC coverage: 63.332%. First build
15445734801

push

github

rkorytkowski
TRUNK-6345 Fix testing framework to be used by modules for openmrs-core 2.4+

5 of 10 new or added lines in 2 files covered. (50.0%)

21403 of 33795 relevant lines covered (63.33%)

0.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

40.0
/api/src/main/java/org/openmrs/logging/OpenmrsConfigurationFactory.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.logging;
11

12
import javax.validation.constraints.NotNull;
13
import java.io.File;
14
import java.net.URI;
15
import java.util.Locale;
16

17
import org.apache.commons.io.FilenameUtils;
18
import org.apache.commons.lang3.StringUtils;
19
import org.apache.logging.log4j.Level;
20
import org.apache.logging.log4j.core.LoggerContext;
21
import org.apache.logging.log4j.core.config.AbstractConfiguration;
22
import org.apache.logging.log4j.core.config.Configuration;
23
import org.apache.logging.log4j.core.config.ConfigurationFactory;
24
import org.apache.logging.log4j.core.config.ConfigurationSource;
25
import org.apache.logging.log4j.core.config.LoggerConfig;
26
import org.apache.logging.log4j.core.config.Order;
27
import org.apache.logging.log4j.core.config.json.JsonConfiguration;
28
import org.apache.logging.log4j.core.config.plugins.Plugin;
29
import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
30
import org.apache.logging.log4j.core.config.yaml.YamlConfiguration;
31
import org.openmrs.api.AdministrationService;
32
import org.openmrs.api.ServiceNotFoundException;
33
import org.openmrs.api.context.Context;
34
import org.openmrs.util.OpenmrsConstants;
35
import org.openmrs.util.OpenmrsUtil;
36
import org.slf4j.LoggerFactory;
37

38
/**
39
 * {@link ConfigurationFactory} to handle OpenMRS's logging configuration.
40
 * <p/>
41
 * Functionality provided by this {@link ConfigurationFactory}:
42
 * <ul>
43
 *     <li>Load log4j2 configuration files from the OpenMRS application directory</li>
44
 *     <li>Ensures that the configuration includes the MEMORY_APPENDER to keep log files in memory</li>
45
 *     <li>Allows the <tt>log.level</tt> setting to override logger settings</li>
46
 * </ul>
47
 */
48
@Plugin(name = "OpenmrsConfigurationFactory", category = ConfigurationFactory.CATEGORY)
49
@Order(10)
50
@SuppressWarnings("unused")
51
public class OpenmrsConfigurationFactory extends ConfigurationFactory {
1✔
52
        
53
        private static final org.slf4j.Logger log = LoggerFactory.getLogger(OpenmrsConfigurationFactory.class);
1✔
54
        
55
        public static final String[] SUFFIXES = new String[] { ".xml", ".yml", ".yaml", ".json", "*" };
1✔
56
        
57
        @Override
58
        public Configuration getConfiguration(LoggerContext loggerContext, String name, URI configLocation) {
59
                if (!isActive()) {
1✔
60
                        return null;
×
61
                }
62
                
63
                if (configLocation == null) {
1✔
64
                        // Try to load the configuration from the application directory
65
                        for (File applicationDirectory : new File[] {
1✔
66
                                OpenmrsUtil.getDirectoryInApplicationDataDirectory("configuration"),
1✔
67
                                OpenmrsUtil.getApplicationDataDirectoryAsFile()
1✔
68
                         }) {
69
                                for (String suffix : getSupportedTypes()) {
1✔
70
                                        if (suffix.equals("*")) {
1✔
71
                                                continue;
1✔
72
                                        }
73
                                        
74
                                        File configFile = new File(applicationDirectory, getDefaultPrefix() + suffix);
1✔
75
                                        if (configFile.exists() && configFile.canRead()) {
1✔
76
                                                return super.getConfiguration(loggerContext, name, configFile.toURI());
×
77
                                        }
78
                                }
79
                        }
80
                }
81

82
                return super.getConfiguration(loggerContext, name, configLocation);
1✔
83
        }
84

85
        @Override
86
        public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) {
87
                if (source != null && source.getFile() != null) {
1✔
88
                        switch (FilenameUtils.getExtension(source.getFile().getName()).toLowerCase(Locale.ROOT)) {
1✔
89
                                case "xml":
90
                                        return new OpenmrsXmlConfiguration(loggerContext, source);
1✔
91
                                case "yaml":
92
                                case "yml":
NEW
93
                                        return new OpenmrsYamlConfiguration(loggerContext, source);
×
94
                                case "json":
NEW
95
                                        return new OpenmrsJsonConfiguration(loggerContext, source);
×
96
                                default:
NEW
97
                                        throw new IllegalArgumentException(
×
NEW
98
                                                OpenmrsConfigurationFactory.class.getName() + " does not know how to handle source " + source.getFile());
×
99
                        }
100
                }
NEW
101
                return null;
×
102
        }
103
        
104
        @Override
105
        protected String[] getSupportedTypes() {
106
                return SUFFIXES;
1✔
107
        }
108
        
109
        protected static void doOpenmrsCustomisations(AbstractConfiguration configuration) {
110
                // if we don't have an in-memory appender, add it
111
                MemoryAppender memoryAppender = configuration.getAppender(OpenmrsConstants.MEMORY_APPENDER_NAME);
1✔
112
                if (memoryAppender == null) {
1✔
113
                        memoryAppender = MemoryAppender.newBuilder().build();
1✔
114
                        memoryAppender.start();
1✔
115
                        
116
                        configuration.addAppender(memoryAppender);
1✔
117
                }
118
                
119
                LoggerConfig rootLogger = configuration.getRootLogger();
1✔
120
                if (rootLogger.getAppenders().get(OpenmrsConstants.MEMORY_APPENDER_NAME) == null) {
1✔
121
                        rootLogger.addAppender(memoryAppender, null, memoryAppender.getFilter());
1✔
122
                }
123
                
124
                try {
125
                        AdministrationService adminService = Context.getAdministrationService();
×
126
                        applyLogLevels(configuration, adminService);
×
127
                } catch (ServiceNotFoundException e) {
1✔
128
                        // if AdministrativeService is not available, we'll assume we're starting up and everything is ok
129
                        if (!e.getServiceClass().isAssignableFrom(AdministrationService.class)) {
1✔
130
                                throw e;
×
131
                        }
132
                }
×
133
        }
1✔
134
        
135
        private static void applyLogLevels(AbstractConfiguration configuration, AdministrationService adminService) {
136
                String logLevel = adminService.getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_LOG_LEVEL, "");
×
137
                
138
                for (String level : logLevel.split(",")) {
×
139
                        String[] classAndLevel = level.split(":");
×
140
                        if (classAndLevel.length == 0) {
×
141
                                break;
×
142
                        } else if (classAndLevel.length == 1) {
×
143
                                applyLogLevel(configuration, OpenmrsConstants.LOG_CLASS_DEFAULT, classAndLevel[0].trim());
×
144
                        } else {
145
                                applyLogLevel(configuration, classAndLevel[0].trim(), classAndLevel[1].trim());
×
146
                        }
147
                }
148
        }
×
149
        
150
        private static void applyLogLevel(AbstractConfiguration configuration, @NotNull String loggerName, String loggerLevel) {
151
                if (StringUtils.isBlank(loggerLevel)) {
×
152
                        return;
×
153
                }
154
                
155
                if (loggerName == null) {
×
156
                        loggerName = OpenmrsConstants.LOG_CLASS_DEFAULT;
×
157
                }
158
                
159
                LoggerConfig loggerConfig = configuration.getLogger(loggerName);
×
160
                if (loggerConfig != null) {
×
161
                        switch (loggerLevel.toLowerCase(Locale.ROOT)) {
×
162
                                case OpenmrsConstants.LOG_LEVEL_TRACE:
163
                                        loggerConfig.setLevel(Level.TRACE);
×
164
                                        break;
×
165
                                case OpenmrsConstants.LOG_LEVEL_DEBUG:
166
                                        loggerConfig.setLevel(Level.DEBUG);
×
167
                                        break;
×
168
                                case OpenmrsConstants.LOG_LEVEL_INFO:
169
                                        loggerConfig.setLevel(Level.INFO);
×
170
                                        break;
×
171
                                case OpenmrsConstants.LOG_LEVEL_WARN:
172
                                        loggerConfig.setLevel(Level.WARN);
×
173
                                        break;
×
174
                                case OpenmrsConstants.LOG_LEVEL_ERROR:
175
                                        loggerConfig.setLevel(Level.ERROR);
×
176
                                        break;
×
177
                                case OpenmrsConstants.LOG_LEVEL_FATAL:
178
                                        loggerConfig.setLevel(Level.FATAL);
×
179
                                        break;
×
180
                                default:
181
                                        log.warn("Log level {} is invalid. " +
×
182
                                                "Valid values are trace, debug, info, warn, error or fatal", loggerLevel);
183
                                        break;
184
                        }
185
                }
186
        }
×
187
        
188
        private static class OpenmrsXmlConfiguration extends XmlConfiguration {
189
                
190
                public OpenmrsXmlConfiguration(LoggerContext loggerContext, ConfigurationSource configSource) {
191
                        super(loggerContext, configSource);
1✔
192
                }
1✔
193
                
194
                @Override
195
                protected void doConfigure() {
196
                        super.doConfigure();
1✔
197
                        doOpenmrsCustomisations(this);
1✔
198
                }
1✔
199
        }
200
        
201
        private static class OpenmrsYamlConfiguration extends YamlConfiguration {
202
                
203
                public OpenmrsYamlConfiguration(LoggerContext loggerContext, ConfigurationSource configSource) {
204
                        super(loggerContext, configSource);
×
205
                }
×
206
                
207
                @Override
208
                protected void doConfigure() {
209
                        super.doConfigure();
×
210
                        doOpenmrsCustomisations(this);
×
211
                }
×
212
        }
213
        
214
        private static class OpenmrsJsonConfiguration extends JsonConfiguration {
215
                
216
                public OpenmrsJsonConfiguration(LoggerContext loggerContext, ConfigurationSource configSource) {
217
                        super(loggerContext, configSource);
×
218
                }
×
219
                
220
                @Override
221
                protected void doConfigure() {
222
                        super.doConfigure();
×
223
                        doOpenmrsCustomisations(this);
×
224
                }
×
225
        }
226
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc