2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org
.argeo
.security
.log4j
;
19 import java
.util
.Iterator
;
20 import java
.util
.List
;
21 import java
.util
.Properties
;
23 import org
.apache
.log4j
.AppenderSkeleton
;
24 import org
.apache
.log4j
.Level
;
25 import org
.apache
.log4j
.Logger
;
26 import org
.apache
.log4j
.PropertyConfigurator
;
27 import org
.apache
.log4j
.spi
.LoggingEvent
;
28 import org
.argeo
.ArgeoException
;
29 import org
.argeo
.ArgeoLogListener
;
30 import org
.springframework
.security
.Authentication
;
31 import org
.springframework
.security
.context
.SecurityContext
;
32 import org
.springframework
.security
.context
.SecurityContextHolder
;
33 import org
.springframework
.security
.providers
.anonymous
.AnonymousAuthenticationToken
;
35 /** Not meant to be used directly in standard log4j config */
36 public class SecureLogger
{
37 private List
<ArgeoLogListener
> listeners
;
39 private Boolean disabled
= false;
41 private String level
= null;
43 private Level log4jLevel
= null;
44 // private Layout layout;
46 private Properties configuration
;
48 private AppenderImpl appender
;
50 /** Marker to prevent stack overflow */
51 private ThreadLocal
<Boolean
> dispatching
= new ThreadLocal
<Boolean
>() {
54 protected Boolean
initialValue() {
61 // if (layout != null)
64 // setLayout(new PatternLayout(pattern));
65 appender
= new AppenderImpl();
67 if (configuration
!= null)
68 PropertyConfigurator
.configure(configuration
);
70 Logger
.getRootLogger().addAppender(appender
);
71 } catch (Exception e
) {
72 throw new ArgeoException("Cannot initialize log4j");
76 public void destroy() throws Exception
{
77 Logger
.getRootLogger().removeAppender(appender
);
80 // public void setLayout(Layout layout) {
81 // this.layout = layout;
84 /** For development purpose, since using regular logging is not easy here */
85 static void stdOut(Object obj
) {
86 System
.out
.println(obj
);
89 // public void setPattern(String pattern) {
90 // this.pattern = pattern;
93 public void setDisabled(Boolean disabled
) {
94 this.disabled
= disabled
;
97 public void setLevel(String level
) {
101 public void setListeners(List
<ArgeoLogListener
> listeners
) {
102 this.listeners
= listeners
;
105 public void setConfiguration(Properties configuration
) {
106 this.configuration
= configuration
;
109 private class AppenderImpl
extends AppenderSkeleton
{
110 public boolean requiresLayout() {
114 public void close() {
118 protected void append(LoggingEvent event
) {
122 if (dispatching
.get())
125 if (level
!= null && !level
.trim().equals("")) {
126 if (log4jLevel
== null || !log4jLevel
.toString().equals(level
))
128 log4jLevel
= Level
.toLevel(level
);
129 } catch (Exception e
) {
131 .println("Log4j level could not be set for level '"
132 + level
+ "', resetting it to null.");
137 if (log4jLevel
!= null
138 && !event
.getLevel().isGreaterOrEqual(log4jLevel
)) {
144 Thread currentThread
= Thread
.currentThread();
145 String username
= null;
148 SecurityContext securityContext
= SecurityContextHolder
150 if (securityContext
!= null) {
151 Authentication authentication
= securityContext
152 .getAuthentication();
153 if (authentication
!= null) {
154 if (authentication
instanceof AnonymousAuthenticationToken
) {
157 username
= authentication
.getName();
163 Iterator
<ArgeoLogListener
> it
= listeners
.iterator();
164 while (it
.hasNext()) {
165 ArgeoLogListener logListener
= it
.next();
166 logListener
.appendLog(username
, event
.getTimeStamp(), event
167 .getLevel().toString(), event
.getLoggerName(),
168 currentThread
.getName(), event
.getMessage(), event
.getThrowableStrRep());
170 } catch (Exception e
) {
171 stdOut("Cannot process logging event");