001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements. See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache license, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License. You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the license for the specific language governing permissions and
015     * limitations under the license.
016     */
017    package org.apache.logging.log4j.core.jmx;
018    
019    import java.util.List;
020    import java.util.concurrent.Executor;
021    import java.util.concurrent.atomic.AtomicLong;
022    
023    import javax.management.MBeanNotificationInfo;
024    import javax.management.Notification;
025    import javax.management.NotificationBroadcasterSupport;
026    import javax.management.ObjectName;
027    
028    import org.apache.logging.log4j.Level;
029    import org.apache.logging.log4j.status.StatusData;
030    import org.apache.logging.log4j.status.StatusListener;
031    import org.apache.logging.log4j.status.StatusLogger;
032    
033    /**
034     * Implementation of the {@code StatusLoggerAdminMBean} interface.
035     */
036    public class StatusLoggerAdmin extends NotificationBroadcasterSupport implements
037            StatusListener, StatusLoggerAdminMBean {
038    
039        private final AtomicLong sequenceNo = new AtomicLong();
040        private final ObjectName objectName;
041    
042        /**
043         * Constructs a new {@code StatusLoggerAdmin} with the {@code Executor} to
044         * be used for sending {@code Notification}s asynchronously to listeners.
045         * 
046         * @param executor used to send notifications asynchronously
047         */
048        public StatusLoggerAdmin(Executor executor) {
049            super(executor, createNotificationInfo());
050            try {
051                objectName = new ObjectName(NAME);
052            } catch (Exception e) {
053                throw new IllegalStateException(e);
054            }
055            StatusLogger.getLogger().registerListener(this);
056        }
057    
058        private static MBeanNotificationInfo createNotificationInfo() {
059            String[] notifTypes = new String[] {//
060            NOTIF_TYPE_DATA, NOTIF_TYPE_MESSAGE };
061            String name = Notification.class.getName();
062            String description = "StatusLogger has logged an event";
063            return new MBeanNotificationInfo(notifTypes, name, description);
064        }
065    
066        @Override
067        public String[] getStatusDataHistory() {
068            List<StatusData> data = getStatusData();
069            String[] result = new String[data.size()];
070            for (int i = 0; i < result.length; i++) {
071                result[i] = data.get(i).getFormattedStatus();
072            }
073            return result;
074        }
075    
076        @Override
077        public List<StatusData> getStatusData() {
078            return StatusLogger.getLogger().getStatusData();
079        }
080    
081        @Override
082        public String getLevel() {
083            return StatusLogger.getLogger().getLevel().name();
084        }
085    
086        @Override
087        public void setLevel(String level) {
088            StatusLogger.getLogger().setLevel(Level.valueOf(level));
089        }
090    
091        /*
092         * (non-Javadoc)
093         * 
094         * @see
095         * org.apache.logging.log4j.status.StatusListener#log(org.apache.logging
096         * .log4j.status.StatusData)
097         */
098        @Override
099        public void log(StatusData data) {
100            Notification notifMsg = new Notification(NOTIF_TYPE_MESSAGE,
101                    getObjectName(), nextSeqNo(), now(), data.getFormattedStatus());
102            sendNotification(notifMsg);
103    
104            Notification notifData = new Notification(NOTIF_TYPE_DATA,
105                    getObjectName(), nextSeqNo(), now());
106            notifData.setUserData(data);
107            sendNotification(notifData);
108        }
109    
110        /**
111         * Returns the {@code ObjectName} of this mbean.
112         * 
113         * @return the {@code ObjectName}
114         * @see StatusLoggerAdminMBean#NAME
115         */
116        public ObjectName getObjectName() {
117            return objectName;
118        }
119    
120        private long nextSeqNo() {
121            return sequenceNo.getAndIncrement();
122        }
123    
124        private long now() {
125            return System.currentTimeMillis();
126        }
127    }