001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.api;
028 import org.opends.messages.Message;
029
030
031
032 import java.util.HashMap;
033 import java.util.List;
034 import java.util.Map;
035 import java.util.TreeMap;
036
037 import com.sleepycat.je.Transaction;
038 import com.sleepycat.je.Database;
039 import com.sleepycat.je.DatabaseEntry;
040 import com.sleepycat.je.OperationStatus;
041
042 import org.opends.server.admin.std.server.DebugLogPublisherCfg;
043 import org.opends.server.config.ConfigException;
044 import org.opends.server.loggers.LogLevel;
045 import org.opends.server.loggers.debug.TraceSettings;
046 import org.opends.server.types.DebugLogLevel;
047 import org.opends.server.types.InitializationException;
048 import org.opends.server.types.DN;
049
050
051
052 /**
053 * This class defines the set of methods and structures that must be
054 * implemented for a Directory Server debug log publisher.
055 *
056 * @param <T> The type of debug log publisher configuration handled
057 * by this log publisher implementation.
058 */
059 @org.opends.server.types.PublicAPI(
060 stability=org.opends.server.types.StabilityLevel.VOLATILE,
061 mayInstantiate=false,
062 mayExtend=true,
063 mayInvoke=false)
064 public abstract class DebugLogPublisher
065 <T extends DebugLogPublisherCfg>
066 {
067 //The default global settings key.
068 private static final String GLOBAL= "_global";
069
070 //The map of class names to their trace settings.
071 private Map<String,TraceSettings> classTraceSettings;
072
073 //The map of class names to their method trace settings.
074 private Map<String,Map<String,TraceSettings>> methodTraceSettings;
075
076
077
078 /**
079 * Construct a default configuration where the global scope will
080 * only log at the ERROR level.
081 */
082 protected DebugLogPublisher()
083 {
084 classTraceSettings = null;
085 methodTraceSettings = null;
086
087 //Set the global settings so that only errors are logged.
088 addTraceSettings(null, new TraceSettings(DebugLogLevel.ERROR));
089 }
090
091
092
093 /**
094 * Initializes this debug publisher provider based on the
095 * information in the provided debug publisher configuration.
096 *
097 * @param config The debug publisher configuration that contains
098 * the information to use to initialize this debug
099 * publisher.
100 *
101 * @throws ConfigException If an unrecoverable problem arises in
102 * the process of performing the
103 * initialization as a result of the
104 * server configuration.
105 *
106 * @throws InitializationException If a problem occurs during
107 * initialization that is not
108 * related to the server
109 * configuration.
110 */
111 public abstract void initializeDebugLogPublisher(T config)
112 throws ConfigException, InitializationException;
113
114
115
116 /**
117 * Indicates whether the provided configuration is acceptable for
118 * this debug log publisher. It should be possible to call this
119 * method on an uninitialized debug log publisher instance in
120 * order to determine whether the debug log publisher would be able
121 * to use the provided configuration.
122 * <BR><BR>
123 * Note that implementations which use a subclass of the provided
124 * configuration class will likely need to cast the configuration
125 * to the appropriate subclass type.
126 *
127 * @param configuration The debug log publisher
128 * configuration for which to make the
129 * determination.
130 * @param unacceptableReasons A list that may be used to hold the
131 * reasons that the provided
132 * configuration is not acceptable.
133 *
134 * @return {@code true} if the provided configuration is acceptable
135 * for this debug log publisher, or {@code false} if not.
136 */
137 public boolean isConfigurationAcceptable(
138 DebugLogPublisherCfg configuration,
139 List<Message> unacceptableReasons)
140 {
141 // This default implementation does not perform any special
142 // validation. It should be overridden by debug log publisher
143 // implementations that wish to perform more detailed validation.
144 return true;
145 }
146
147
148
149 /**
150 * Gets the method trace levels for a specified class.
151 *
152 * @param className The fully-qualified name of the class for
153 * which to get the trace levels.
154 *
155 *@return An unmodifiable map of trace levels keyed by method name,
156 * or {@code null} if no method-level tracing is configured
157 * for the scope.
158 */
159 public final Map<String,TraceSettings> getMethodSettings(
160 String className)
161 {
162 if(methodTraceSettings == null)
163 {
164 return null;
165 }
166 else
167 {
168 return methodTraceSettings.get(className);
169 }
170 }
171
172
173
174 /**
175 * Get the trace settings for a specified class.
176 *
177 * @param className The fully-qualified name of the class for
178 * which to get the trace levels.
179 *
180 * @return The current trace settings for the class.
181 */
182 public final TraceSettings getClassSettings(String className)
183 {
184 TraceSettings settings = TraceSettings.DISABLED;
185
186 // If we're not enabled, trace level is DISABLED.
187 if (classTraceSettings != null) {
188 // Find most specific trace setting which covers this
189 // fully qualified class name
190 // Search up the hierarchy for a match.
191 String searchName= className;
192 Object value= null;
193 value= classTraceSettings.get(searchName);
194 while (value == null && searchName != null) {
195 int clipPoint= searchName.lastIndexOf('$');
196 if (clipPoint == -1) clipPoint= searchName.lastIndexOf('.');
197 if (clipPoint != -1) {
198 searchName= searchName.substring(0, clipPoint);
199 value= classTraceSettings.get(searchName);
200 }
201 else {
202 searchName= null;
203 }
204 }
205
206 // Use global settings, if nothing more specific was found.
207 if (value == null) value= classTraceSettings.get(GLOBAL);
208
209 if (value != null) {
210 settings= (TraceSettings)value;
211 }
212 }
213 return settings;
214 }
215
216
217
218 /**
219 * Adds a trace settings to the current set for a specified scope.
220 * If a scope is not specified, the settings will be set for the
221 * global scope. The global scope settings are used when no other
222 * scope matches.
223 *
224 * @param scope The scope for which to set the trace settings.
225 * This should be a fully-qualified class name, or
226 * {@code null} to set the trace settings for the
227 * global scope.
228 * @param settings The trace settings for the specified scope.
229 */
230 public final void addTraceSettings(String scope,
231 TraceSettings settings)
232 {
233 if (scope == null) {
234 setClassSettings(GLOBAL, settings);
235 }
236 else {
237 int methodPt= scope.lastIndexOf('#');
238 if (methodPt != -1) {
239 String methodName= scope.substring(methodPt+1);
240 scope= scope.substring(0, methodPt);
241 setMethodSettings(scope, methodName, settings);
242 }
243 else {
244 setClassSettings(scope, settings);
245 }
246 }
247 }
248
249
250
251 /**
252 * Determine whether a trace setting is already defined for a
253 * particular scope.
254 *
255 * @param scope The scope for which to make the determination.
256 * This should be a fully-qualified class name, or
257 * {@code null} to make the determination for the
258 * global scope.
259 *
260 * @return The trace settings for the specified scope, or
261 * {@code null} if no trace setting is defined for that
262 * scope.
263 */
264 public final TraceSettings getTraceSettings(String scope)
265 {
266 if (scope == null) {
267 if(classTraceSettings != null)
268 {
269 return classTraceSettings.get(GLOBAL);
270 }
271 return null;
272 }
273 else {
274 int methodPt= scope.lastIndexOf('#');
275 if (methodPt != -1) {
276 String methodName= scope.substring(methodPt+1);
277 scope= scope.substring(0, methodPt);
278 if(methodTraceSettings != null)
279 {
280 Map<String, TraceSettings> methodLevels =
281 methodTraceSettings.get(scope);
282 if(methodLevels != null)
283 {
284 return methodLevels.get(methodName);
285 }
286 return null;
287 }
288 return null;
289 }
290 else {
291 if(classTraceSettings != null)
292 {
293 return classTraceSettings.get(scope);
294 }
295 return null;
296 }
297 }
298 }
299
300
301
302 /**
303 * Remove a trace setting by scope.
304 *
305 * @param scope The scope for which to remove the trace setting.
306 * This should be a fully-qualified class name, or
307 * {@code null} to remove the trace setting for the
308 * global scope.
309 *
310 * @return The trace settings for the specified scope, or
311 * {@code null} if no trace setting is defined for that
312 * scope.
313 */
314 public final TraceSettings removeTraceSettings(String scope)
315 {
316 TraceSettings removedSettings = null;
317 if (scope == null) {
318 if(classTraceSettings != null)
319 {
320 removedSettings = classTraceSettings.remove(GLOBAL);
321 }
322 }
323 else {
324 int methodPt= scope.lastIndexOf('#');
325 if (methodPt != -1) {
326 String methodName= scope.substring(methodPt+1);
327 scope= scope.substring(0, methodPt);
328 if(methodTraceSettings != null)
329 {
330 Map<String, TraceSettings> methodLevels =
331 methodTraceSettings.get(scope);
332 if(methodLevels != null)
333 {
334 removedSettings = methodLevels.remove(methodName);
335 if(methodLevels.isEmpty())
336 {
337 methodTraceSettings.remove(scope);
338 }
339 }
340 }
341 }
342 else {
343 if(classTraceSettings != null)
344 {
345 removedSettings = classTraceSettings.remove(scope);
346 }
347 }
348 }
349
350 return removedSettings;
351 }
352
353
354
355 /**
356 * Set the trace settings for a class.
357 *
358 * @param className The class name.
359 * @param settings The trace settings for the class.
360 */
361 private synchronized final void setClassSettings(String className,
362 TraceSettings settings)
363 {
364 if(classTraceSettings == null) classTraceSettings =
365 new HashMap<String, TraceSettings>();
366
367 classTraceSettings.put(className, settings);
368 }
369
370
371
372 /**
373 * Set the method settings for a particular method in a class.
374 *
375 * @param className The class name.
376 * @param methodName The method name.
377 * @param settings The trace settings for the method.
378 */
379 private synchronized final void setMethodSettings(String className,
380 String methodName,
381 TraceSettings settings)
382 {
383 if (methodTraceSettings == null) methodTraceSettings =
384 new HashMap<String, Map<String, TraceSettings>>();
385 Map<String, TraceSettings> methodLevels=
386 methodTraceSettings.get(className);
387 if (methodLevels == null) {
388 methodLevels= new TreeMap<String, TraceSettings>();
389 methodTraceSettings.put(className, methodLevels);
390 }
391
392 methodLevels.put(methodName, settings);
393 }
394
395
396
397 /**
398 * Log a constructor entry.
399 *
400 * @param level The log level for the message.
401 * @param settings The current trace settings in effect.
402 * @param signature The constuctor signature.
403 * @param sourceLocation The location of the method in the source.
404 * @param args The parameters provided to the
405 * constructor.
406 * @param stackTrace The stack trace at the time the
407 * constructor is executed or null if its
408 * not available.
409 */
410 public abstract void traceConstructor(LogLevel level,
411 TraceSettings settings,
412 String signature,
413 String sourceLocation,
414 Object[] args,
415 StackTraceElement[] stackTrace);
416
417
418
419 /**
420 * Log a non-static method entry.
421 *
422 * @param level The log level for the message.
423 * @param settings The current trace settings in effect.
424 * @param signature The method signature.
425 * @param sourceLocation The location of the method in the source.
426 * @param obj The object instance on which the method
427 * has been invoked.
428 * @param args The parameters provided to the method.
429 * @param stackTrace The stack trace at the time the method
430 * is executed or null if its not available.
431 */
432 public abstract void traceMethodEntry(LogLevel level,
433 TraceSettings settings,
434 String signature,
435 String sourceLocation,
436 Object obj,
437 Object[] args,
438 StackTraceElement[] stackTrace);
439
440
441
442 /**
443 * Log a static method entry.
444 *
445 * @param level The log level for the message.
446 * @param settings The current trace settings in effect.
447 * @param signature The method signature.
448 * @param sourceLocation The location of the method in the source.
449 * @param args The parameters provided to the method.
450 * @param stackTrace The stack trace at the time the method
451 * is executed or null if its not available.
452 */
453 public abstract void traceStaticMethodEntry(LogLevel level,
454 TraceSettings settings,
455 String signature,
456 String sourceLocation,
457 Object[] args,
458 StackTraceElement[] stackTrace);
459
460
461
462 /**
463 * Log a method return.
464 *
465 * @param level The log level for the message.
466 * @param settings The current trace settings in effect.
467 * @param signature The method signature.
468 * @param sourceLocation The location of the method in the source.
469 * @param ret The return value for the method.
470 * @param stackTrace The stack trace at the time the method
471 * is returned or null if its not available.
472 */
473 public abstract void traceReturn(LogLevel level,
474 TraceSettings settings,
475 String signature,
476 String sourceLocation,
477 Object ret,
478 StackTraceElement[] stackTrace);
479
480
481
482 /**
483 * Log an arbitrary event in a method.
484 *
485 * @param level The log level for the message.
486 * @param settings The current trace settings in effect.
487 * @param signature The method signature.
488 * @param sourceLocation The location of the method in the source.
489 * @param msg The message to be logged.
490 * @param stackTrace The stack trace at the time the message
491 * is logged or null if its not available.
492 */
493 public abstract void traceMessage(LogLevel level,
494 TraceSettings settings,
495 String signature,
496 String sourceLocation,
497 String msg,
498 StackTraceElement[] stackTrace);
499
500
501
502 /**
503 * Log a thrown exception in a method.
504 *
505 * @param level The log level for the message.
506 * @param settings The current trace settings in effect.
507 * @param signature The method signature.
508 * @param sourceLocation The location of the method in the source.
509 * @param ex The exception that was thrown.
510 * @param stackTrace The stack trace at the time the exception
511 * is thrown or null if its not available.
512 */
513 public abstract void traceThrown(LogLevel level,
514 TraceSettings settings,
515 String signature,
516 String sourceLocation,
517 Throwable ex,
518 StackTraceElement[] stackTrace);
519
520
521
522 /**
523 * Log a caught exception in a method.
524 *
525 * @param level The log level for the message.
526 * @param settings The current trace settings in effect.
527 * @param signature The method signature.
528 * @param sourceLocation The location of the method in the source.
529 * @param ex The exception that was caught.
530 * @param stackTrace The stack trace at the time the exception
531 * is caught or null if its not available.
532 */
533 public abstract void traceCaught(LogLevel level,
534 TraceSettings settings,
535 String signature,
536 String sourceLocation,
537 Throwable ex,
538 StackTraceElement[] stackTrace);
539
540
541
542 /**
543 * Log an JE database access in a method.
544 *
545 * @param level The log level for the message.
546 * @param settings The current trace settings in effect.
547 * @param signature The method signature.
548 * @param sourceLocation The location of the method in the source.
549 * @param status The status of the JE operation.
550 * @param database The database handle.
551 * @param txn The transaction handle (may be
552 * {@code null}).
553 * @param key The key to dump.
554 * @param data The data to dump.
555 * @param stackTrace The stack trace at the time the access
556 * occurred or null if its not available.
557 */
558 public abstract void traceJEAccess(LogLevel level,
559 TraceSettings settings,
560 String signature,
561 String sourceLocation,
562 OperationStatus status,
563 Database database,
564 Transaction txn,
565 DatabaseEntry key,
566 DatabaseEntry data,
567 StackTraceElement[] stackTrace);
568
569
570
571 /**
572 * Log raw data in a method.
573 *
574 * @param level The log level for the message.
575 * @param settings The current trace settings in effect.
576 * @param signature The method signature.
577 * @param sourceLocation The location of the method in the source.
578 * @param data The data to dump.
579 * @param stackTrace The stack trace at the time the data
580 * is logged or null if its not available.
581 */
582 public abstract void traceData(LogLevel level,
583 TraceSettings settings,
584 String signature,
585 String sourceLocation,
586 byte[] data,
587 StackTraceElement[] stackTrace);
588
589
590
591 /**
592 * Log a protocol element in a method.
593 *
594 * @param level The log level for the message.
595 * @param settings The current trace settings in effect.
596 * @param signature The method signature.
597 * @param sourceLocation The location of the method in the source.
598 * @param element The protocol element to dump.
599 * @param stackTrace The stack trace at the time the protocol
600 * element is logged or null if its not
601 * available.
602 */
603 public abstract void traceProtocolElement(LogLevel level,
604 TraceSettings settings,
605 String signature,
606 String sourceLocation,
607 ProtocolElement element,
608 StackTraceElement[] stackTrace);
609
610 /**
611 * Close this publisher.
612 */
613 public abstract void close();
614
615 /**
616 * Gets the DN of the configuration entry for this debug log
617 * publisher.
618 *
619 * @return The configuration entry DN.
620 */
621 public abstract DN getDN();
622 }
623