summaryrefslogtreecommitdiffstats
path: root/valetapi/src/main/java/org/onap/fgps/api/eelf/configuration/EELFManager.java
blob: a0967489e6a9afc1c91de50530f26565e4175114 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
/* 
 * ============LICENSE_START========================================== 
 * ONAP - F-GPS API 
 * =================================================================== 
 * Copyright © 2019 ATT Intellectual Property. All rights reserved. 
 * =================================================================== 
 * 
 * Unless otherwise specified, all software contained herein is licensed 
 * under the Apache License, Version 2.0 (the "License"); 
 * you may not use this software except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *             http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 * 
 * Unless otherwise specified, all documentation contained herein is licensed 
 * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); 
 * you may not use this documentation except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *             https://creativecommons.org/licenses/by/4.0/ 
 * 
 * Unless required by applicable law or agreed to in writing, documentation 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 * 
 * ============LICENSE_END============================================ 
 * 
 * 
 */
package org.onap.fgps.api.eelf.configuration;

import static org.onap.fgps.api.eelf.configuration.Configuration.AUDIT_LOGGER_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.DEBUG_LOGGER_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.ERROR_LOGGER_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.GENERAL_LOGGER_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.METRICS_LOGGER_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.PERF_LOGGER_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.POLICY_LOGGER_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.PROPERTY_LOGGING_FILE_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.PROPERTY_LOGGING_FILE_PATH;
import static org.onap.fgps.api.eelf.configuration.Configuration.SECURITY_LOGGER_NAME;
import static org.onap.fgps.api.eelf.configuration.Configuration.SERVER_LOGGER_NAME;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.onap.fgps.api.eelf.i18n.EELFMsgs;
import org.onap.fgps.api.eelf.i18n.EELFResourceManager;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;

/**
 * This is a singleton class used to obtain a named Logger instance.
 * The EELFManager object can be retrieved using EELFManager.getInstance(). It is created during class initialization and cannot subsequently be changed.
 * At startup the EELFManager loads the logging configuration file.
 * If no external logging configuration file is found, it will load the default logging configuration available at org/onap/eelf/logback.xml
 */

public final class EELFManager {
	
	/**
     * This is a string constant for the comma character. It's intended to be used a common string delimiter.
     */
    private static final String COMMA = ",";
	
	/**
     * The logger to be used to record general application log events
     */
    private EELFLogger applicationLogger;

    /**
     * The logger to be used to record audit events
     */
    private EELFLogger auditLogger;

    /**
     * The logger to be used to record metric events
     */
    private EELFLogger metricsLogger;

   
    /**
     * The logger to be used to record performance events
     */
    private EELFLogger performanceLogger;

    /**
     * The logger to be used to record policy manager application events
     */
    private EELFLogger policyLogger;
	
    /**
     * The logger to be used to record security events
     */
	private EELFLogger securityLogger;
    
    /**
     * The logger to be used to record server events
     */
    private EELFLogger serverLogger;
    
    /**
     * The logger to be used to record error only
     */
    private EELFLogger errorLogger;
    
    /**
     * The logger to be used to record debug logs
     */
    private EELFLogger debugLogger;
	
    /**
     * Cache of all other loggers used in application
     */
	private Map<String,EELFLogger> loggerCache = new ConcurrentHashMap<String,EELFLogger>();
	
	/**
     * This lock is used to serialize access to create the loggers
     */
    private Object loggerLock = new Object();
    
    /**
     * This lock is used to serialize access to create the loggers
     */
    private static final EELFManager logManager = new EELFManager();
    
    private EELFManager() {
    	 ArrayList<String> delayedLogging = new ArrayList<String>();
    	 /*
         * Now, we are ready to initialize logging. Check to see if logging has already been initialized and that the
         * application logger exists already. If it does, then skip the logging configuration because it was already set
         * up in the container that is calling us. If not, then we need to set it up.
         */
        ILoggerFactory factory = LoggerFactory.getILoggerFactory();
        if (factory instanceof LoggerContext) {
        	LoggerContext loggerContext = (LoggerContext) factory;
            if (loggerContext.exists(GENERAL_LOGGER_NAME) == null) {
                initializeLogging(delayedLogging);
            } else {
            	delayedLogging.add(EELFResourceManager.getMessage(EELFMsgs.LOGGING_ALREADY_INITIALIZED));             
            }
        }
        
        /*
         * Copy all delayed logging messages to the logger
         */
        for (String message : delayedLogging) {
            // All messages are prefixed with a message code of the form EELF####S
            // Where:
            // EELF --- is the product code
            // #### -- Is the message number
            // S ----- Is the severity code (I=INFO, D=DEBUG, W=WARN, E=ERROR)
            char severity = message.charAt(8);
            switch (severity) {
                case 'D':
                	getApplicationLogger().debug(message);
                    break;
                case 'I':
                	getApplicationLogger().info(message);
                    break;
                case 'W':
                	getApplicationLogger().warn(message);
                    break;
                case 'E':
                	getApplicationLogger().error(message);
            }
        }
        
        delayedLogging.clear();
    	
    }
    
    /**
     * Initialize the logging environment, record all logging messages to the provided list for delayed processing.
     *
     * @param delayedLogging
     *            The list to record logging messages to for delayed processing after the logging environment is
     *            created.
     */
    private static void initializeLogging(final ArrayList<String> delayedLogging) {
    	
    	 /*
         * See if we can find logback-test.xml first, unless a specific file has been provided
         */
        String filename = System.getProperty(PROPERTY_LOGGING_FILE_NAME, "logback-test.xml");
       
        String path = System.getProperty(PROPERTY_LOGGING_FILE_PATH,  "${user.home};etc;../etc");
        
        String msg = EELFResourceManager.format(EELFMsgs.SEARCHING_LOG_CONFIGURATION,path, filename);  
        delayedLogging.add(msg);

        if (scanAndLoadLoggingConfiguration(path, filename, delayedLogging)) {
            return;
        }

        /*
         * If the first attempt was for logback-test.xml and it failed to find it, look again for logback.xml
         */
        if (filename.equals("logback-test.xml")) {
            filename = System.getProperty(PROPERTY_LOGGING_FILE_NAME, "logback.xml");
          
            if (scanAndLoadLoggingConfiguration(path, filename, delayedLogging)) {
                return;
            }
        }
       

        /*
         * If we reach here, then no external logging configurations were defined or found. In that case, we need to
         * initialize the logging framework from hard-coded default values we load from resources.
         */
        InputStream stream = EELFManager.class.getClassLoader().getResourceAsStream("org/onap/eelf/logback.xml");
        try {
            if (stream != null) {
                delayedLogging.add(EELFResourceManager.getMessage(EELFMsgs.LOADING_DEFAULT_LOG_CONFIGURATION,"org/onap/eelf/logback.xml"));
                loadLoggingConfiguration(stream, delayedLogging);
            } else {
            	 delayedLogging.add(EELFResourceManager.format(EELFMsgs.NO_LOG_CONFIGURATION));               
            	 }
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    // not much we can do since logger may not be configured yet
                    e.printStackTrace(System.out);
                }
            }
        }
        
    }
    

    /**
     * Loads the logging configuration from the specified stream.
     *
     * @param stream
     *            The stream that contains the logging configuration document.
     * @param delayedLogging
     */
    private static void loadLoggingConfiguration(final InputStream stream, final ArrayList<String> delayedLogging) {
        ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
        if (loggerFactory instanceof LoggerContext) {
            configureLogback((LoggerContext) loggerFactory, stream);
        } else {
        	 delayedLogging.add((EELFResourceManager.format(EELFMsgs.UNSUPPORTED_LOGGING_FRAMEWORK)));        	
        }
        
    }


    
    /**
     * @param loggerFactory
     *            the logger factory context
     * @param stream
     *            The input stream to be configured
     */
    private static void configureLogback(final LoggerContext context, final InputStream stream) {
        JoranConfigurator configurator = new JoranConfigurator();
        configurator.setContext(context);

        try {
            configurator.doConfigure(stream);
        } catch (JoranException e) {
            // not much we can do since logger may not be configured yet
            e.printStackTrace(System.out);
        }

       
    }
    
    
    /**
     * This method scans a set of directories specified by the path for an occurrence of a file of the specified
     * filename, and when found, loads that file as a logging configuration file.
     *
     * @param path
     *            The path to be scanned. This can be one or more directories, separated by the platform specific path
     *            separator character.
     * @param filename
     *            The file name to be located. The file name examined within each element of the path for the first
     *            occurrence of the file that exists and which can be read and processed.
     * @param delayedLogging
     * @return True if a file was found and loaded, false if no files were found, or none were readable.
     */
    private static boolean scanAndLoadLoggingConfiguration(final String path, final String filename,
        final ArrayList<String> delayedLogging) {
        String[] pathElements = path.split(COMMA);
        for (String pathElement : pathElements) {
            File file = new File(pathElement, filename);
            if (file.exists() && file.canRead() && !file.isDirectory()) {
                String msg = EELFResourceManager.getMessage(EELFMsgs.LOADING_LOG_CONFIGURATION,file.getAbsolutePath());	                
                delayedLogging.add(msg);

                try (BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file));){
                    delayedLogging.add(String.format("EELF000I Loading logging configuration from %s",
                        file.getAbsolutePath()));
                     loadLoggingConfiguration(stream, delayedLogging);
                } catch (FileNotFoundException e) {
                    delayedLogging.add(EELFResourceManager.format(e));
                } catch (IOException e1) {
                	 delayedLogging.add(EELFResourceManager.format(e1));
				} 

                return true;
            }
        }
        return false;
    }

    
    /**
     * This method is used to obtain the EELFManager (as well as set it up if not already).
     *
     * @return The EELFManager object 
     */
    public static EELFManager getInstance() {
    		
    	return logManager;
    }
    
    /**
	 * Returns the logger associated with the name 
	 * @return EELFLogger
	 */
	public EELFLogger getLogger(String name) {
		synchronized (loggerLock) {
			if (!loggerCache.containsKey(name)) {
				loggerCache.put(name,new SLF4jWrapper(name));
			}	
		}	
		return loggerCache.get(name); 
		 
	 }
	
	    /**
     * Returns the logger associated with the clazz
     * 
     * @param clazz
     *            The class that we are obtaining the logger for
     * @return EELFLogger The logger
     */
    public EELFLogger getLogger(Class<?> clazz) {
		synchronized (loggerLock) {
			if (!loggerCache.containsKey(clazz.getName())) {
				loggerCache.put(clazz.getName(), new SLF4jWrapper(clazz.getName()));
			}	
		}	
		return loggerCache.get(clazz.getName());
			 
	}
	
	/**
	 * Returns the  application logger 
	 * @return EELFLogger
	 */
	public EELFLogger getApplicationLogger() {
		 synchronized (loggerLock) {
	          if (applicationLogger == null) {
	        	   applicationLogger = new SLF4jWrapper(GENERAL_LOGGER_NAME);
	          }
	      }
		return applicationLogger; 
	}
	
	/**
	 * Returns the  metrics logger
	 * @return EELFLogger
	 */
	public EELFLogger getMetricsLogger() {
		synchronized (loggerLock) {
	          if (metricsLogger == null) {
	        	  metricsLogger = new SLF4jWrapper(METRICS_LOGGER_NAME);
	          }
	      }
		return metricsLogger; 
	}

	  
	/**
	 * Returns the  audit logger 
	 * @return EELFLogger
	 */
	public EELFLogger getAuditLogger() {
		synchronized (loggerLock) {
	          if (auditLogger == null) {
	        	  auditLogger = new SLF4jWrapper(AUDIT_LOGGER_NAME);
	          }
	      }
		return auditLogger; 
	 }

	/**
	 * Returns the  performance logger 
	 * @return EELFLogger
	 */
	public EELFLogger getPerformanceLogger() {
		synchronized (loggerLock) {
	          if (performanceLogger == null) {
	        	  performanceLogger = new SLF4jWrapper(PERF_LOGGER_NAME);
	          }
	      }
		return performanceLogger; 
	}	
	  
	  /**
	   * Returns the  server logger 
	   * @return EELFLogger
	   */
	public EELFLogger getServerLogger() {
		synchronized (loggerLock) {
	          if (serverLogger == null) {
	        	  serverLogger = new SLF4jWrapper(SERVER_LOGGER_NAME);
	          }
	      }
		return serverLogger; 
	}	
    
	  
	  /**
	   * Returns the  security logger 
	   * @return EELFLogger
	   */
	public  EELFLogger getSecurityLogger() {
		synchronized (loggerLock) {
	          if (securityLogger == null) {
	        	  securityLogger = new SLF4jWrapper(SECURITY_LOGGER_NAME);
	          }
	      }
		return securityLogger; 
	}	
	  
	/**
	  * Returns the policy logger 
	  * @return EELFLogger
	  */
	public EELFLogger getPolicyLogger() {
		synchronized (loggerLock) {
	          if (policyLogger == null) {
	        	  policyLogger = new SLF4jWrapper(POLICY_LOGGER_NAME);
	          }
	      }
		return policyLogger; 
	}
	  
	
	/**
	 * Returns the  error logger 
	 * @return EELFLogger
	 */
	public EELFLogger getErrorLogger() {
		 synchronized (loggerLock) {
	          if (errorLogger == null) {
	        	  errorLogger = new SLF4jWrapper(ERROR_LOGGER_NAME);
	          }
	      }
		return errorLogger; 
	}
		
	/**
	 * Returns the  error logger 
	 * @return EELFLogger
	 */
	public EELFLogger getDebugLogger() {
		 synchronized (loggerLock) {
	          if (debugLogger == null) {
	        	  debugLogger = new SLF4jWrapper(DEBUG_LOGGER_NAME);
	          }
	      }
		return debugLogger; 
	}
	
}