Source code: org/scoja/server/source/Internal.java
1 /** This file has been automatically generated from an .in file. Don't edit it; modify the .in file instead. */
2
3 package org.scoja.server.source;
4
5 import java.net.InetAddress;
6 import java.net.UnknownHostException;
7
8 import org.scoja.common.PriorityUtils;
9 import org.scoja.server.core.ScojaThread;
10 import org.scoja.server.core.Link;
11 import org.scoja.server.core.Event;
12 import org.scoja.server.core.InternalEvent;
13 import org.scoja.server.core.EventContext;
14
15 /**
16 * This is the source of internal events.
17 * It is a singleton.
18 * At configuration scripts, it is accesible through "internal"
19 * variable.
20 * All scripts see the same object; so, it is only necessary to
21 * configure its logging (filters + targets) at one script.
22 * <p>
23 * Logging at Scoja library should use this singleton.
24 * This logging class use a trick to avoid endless chains
25 * of internal events.
26 * As an inevitable side effect, this trick can cut the generation of
27 * some internal logs.
28 * It is important to read carefully this class documentation.
29 *
30 * <p>
31 * <b>Energy</b>
32 * There are two kinds of threads at Scoja.
33 * More frecuent and active threads are those that process events.
34 * But threre are a few threads that do other activies, not directly
35 * related to event processing. For instance, the thread that check
36 * whether configurations files has changed.
37 * When event A processing produce an internal event B, we say that A
38 * is guilty or referece event of B.
39 * <p>
40 * Most internal events are generated at event (external or internal)
41 * processing threads.
42 * So, it is possible that processing an internal event produce
43 * another similar internal event, that produce another similar event,
44 * and so on.
45 * To avoid this endless event chains, every event has an
46 * <i>energy</i>.
47 * When an event E1 produces an internal event E2, this class ensures
48 * that E2 its more critical than E1 (its level is strict less than E1
49 * level) or than its energy is one less than E1 energy.
50 * Each time that an event produces another event, at least one of
51 * level or energy is decreased.
52 * So, there is no way to produce an endless chain of events.
53 * <p>
54 * Sometimes, an event processing thread is executing a code that
55 * wants to produce an internal event but has no way to access to the
56 * event currently been processing.
57 * This is no problem, because event processing threads are not normal
58 * Thread but {@link ScojaThread}.
59 * These special threads always referer to the event they are
60 * processing.
61 * This class has methods with and without explicit event that is
62 * currenlty been processed; when a method without this argument is
63 * used, the current thread is explored to find out the current
64 * event.
65 * <p>
66 * Internal events produced by non-event-processing threads are the
67 * only one that have no guilty event.
68 * But this events cannot produce an endless chain of events because
69 * other internal events produced during processing this internal
70 * event will have a guilty.
71 *
72 * <p>
73 * <b>Easy methods</b>
74 * To make code short an more readable, static methods for every level
75 * are defined.
76 * There are two versions: with and without reference event.
77 * Version with reference event should be used whenever possible.
78 *
79 * <p>
80 * <b>Statically removing unimportant internal events</b>
81 * Internals events to levels less critical than
82 * {@link PriorityUtils#NOTICE} (not included) should be
83 * statically removable, to enhance performance.
84 * So, when sending
85 * to {@link PriorityUtils#INFO}
86 * and {@link PriorityUtils#DEBUG},
87 * it is necessary to nest the calls inside a conditional like:
88 * <code><pre>
89 * if (pretendedLevel <= Internal.LOG_DETAIL) {
90 * Internal.getInstance().log(guiltyEvent, pretendedLevel, "Message");
91 * }
92 * </pre></code>
93 * For instance:
94 * <pre>
95 if (PriorityUtils.DEBUG <= Internal.LOG_DETAIL) {
96 Internal.getInstance().log(env, PriorityUtils.DEBUG, "Message");
97 }
98 * </pre>
99 * or better:
100 * <pre>
101 if (PriorityUtils.DEBUG <= Internal.LOG_DETAIL) {
102 Internal.debug(env, "Message");
103 }
104 * </pre>
105 */
106 public class Internal extends Link {
107
108 private static final Internal internal;
109 static {
110 try {
111 internal = new Internal();
112 } catch (UnknownHostException e) {
113 throw new RuntimeException
114 ("Fatal error: Cannot find localhost address");
115 }
116 }
117
118 public static Internal getInstance() {
119 return internal;
120 }
121
122 // Should be NOTICE for normal operation and DEBUG for debugging mode.
123 public static final int LOG_DETAIL = PriorityUtils.NOTICE;
124
125 protected final InetAddress localhost;
126
127 private Internal() throws UnknownHostException {
128 this.localhost = InetAddress.getLocalHost();
129 }
130
131 public void log(final int level, final String message) {
132 EventContext ectx = null;
133 final Thread thread = Thread.currentThread();
134 if (thread instanceof ScojaThread) {
135 ectx = ((ScojaThread)thread).getEventContext();
136 }
137 if (ectx != null) {
138 log(ectx, level, message);
139 } else {
140 log(InternalEvent.NO_ENERGY, level, message);
141 }
142 }
143
144 public void log(final EventContext guilty,
145 final int level, final String message) {
146 final Event env = guilty.getEvent();
147 int energy = env.getEnergy();
148 if (level >= env.getLevel()) energy--;
149 log(energy, level, message);
150 }
151
152 public void log(final int energy,
153 final int level, final String message) {
154 if (energy < InternalEvent.NO_ENERGY) return;
155 final Event event = new InternalEvent
156 (localhost, energy, PriorityUtils.SYSLOG,level, "syslog", message);
157 final EventContext newECtx = new EventContext(event);
158 final Thread thread = Thread.currentThread();
159 if (thread instanceof ScojaThread) {
160 final ScojaThread sthread = (ScojaThread)thread;
161 final EventContext previousECtx = sthread.setEventContext(newECtx);
162 process(newECtx);
163 sthread.setEventContext(previousECtx);
164 } else {
165 process(newECtx);
166 }
167 }
168
169 public static void emerg(final EventContext env, final String message) {
170 internal.log(env, PriorityUtils.EMERG, message);
171 }
172
173 public static void emerg(final String message) {
174 internal.log(PriorityUtils.EMERG, message);
175 }
176
177 public static void alert(final EventContext env, final String message) {
178 internal.log(env, PriorityUtils.ALERT, message);
179 }
180
181 public static void alert(final String message) {
182 internal.log(PriorityUtils.ALERT, message);
183 }
184
185 public static void crit(final EventContext env, final String message) {
186 internal.log(env, PriorityUtils.CRIT, message);
187 }
188
189 public static void crit(final String message) {
190 internal.log(PriorityUtils.CRIT, message);
191 }
192
193 public static void err(final EventContext env, final String message) {
194 internal.log(env, PriorityUtils.ERR, message);
195 }
196
197 public static void err(final String message) {
198 internal.log(PriorityUtils.ERR, message);
199 }
200
201 public static void warning(final EventContext env, final String message) {
202 internal.log(env, PriorityUtils.WARNING, message);
203 }
204
205 public static void warning(final String message) {
206 internal.log(PriorityUtils.WARNING, message);
207 }
208
209 public static void notice(final EventContext env, final String message) {
210 internal.log(env, PriorityUtils.NOTICE, message);
211 }
212
213 public static void notice(final String message) {
214 internal.log(PriorityUtils.NOTICE, message);
215 }
216
217 public static void info(final EventContext env, final String message) {
218 internal.log(env, PriorityUtils.INFO, message);
219 }
220
221 public static void info(final String message) {
222 internal.log(PriorityUtils.INFO, message);
223 }
224
225 public static void debug(final EventContext env, final String message) {
226 internal.log(env, PriorityUtils.DEBUG, message);
227 }
228
229 public static void debug(final String message) {
230 internal.log(PriorityUtils.DEBUG, message);
231 }
232 }