001/*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: LogRecord.java,v 1.7 2009/03/05 22:55:37 veiming Exp $
026 *
027 * Portions Copyrighted 2016 ForgeRock AS.
028 */
029
030package com.sun.identity.log;
031
032import static org.forgerock.openam.utils.Time.*;
033
034import com.iplanet.sso.SSOException;
035import com.sun.identity.log.spi.Debug;
036import java.text.SimpleDateFormat;
037import java.util.Date;
038import java.util.HashMap;
039import java.util.Hashtable;
040import java.util.Map;
041import java.util.logging.Level;
042
043/**
044 * Extension to the JDK1.4 <code>LogRecord</code> to include the
045 * <code>logInfo</code> <code>HashMap</code> and methods to store and retrieve
046 * data from this <code>logInfo</code> Map. The <code>logInfo</code> Map is
047 * supposed to be used by the client to fill in log-details which
048 * will be used by the Formatter to construct the actual log string.
049 *
050 * For <code>JDK1.4</code> <code>LogRecord</code> please refer to 
051 * <pre>
052 * http://java.sun.com/j2se/1.4.1/docs/api/java/util/logging/LogRecord.html
053 * </pre>
054 * @supported.api
055 */
056public class LogRecord extends java.util.logging.LogRecord
057    implements ILogRecord
058{
059    private Map logInfoMap = new HashMap();
060    private Object token;
061
062    /**
063     * Construct the <code>LogRecord</code> with the given Level and message
064     * values.
065     *
066     * @param level The log Level
067     * @param msg The message string
068     *
069     * @supported.api
070     */
071    public LogRecord(Level level, String msg) {
072        super(level,msg);
073    }
074
075    /**
076     * Construct the <code>LogRecord</code> with the given Level and message
077     * values.
078     *
079     * @param level The log Level.
080     * @param msg The message string.
081     * @param token The single sign-on token which will be used to fill in
082     *        details like client IP address into the <code>LogRecord</code>.
083     * @supported.api
084     */
085    public LogRecord(Level level, String msg, Object token) {
086        this(level,msg);
087        this.token = token;
088
089        try {
090            Logger.extractInfoFromLogFor(this);
091        } catch (SSOException se) {
092            /*
093             *  internal auth session doesn't have IPaddr, so stacktrace
094             *  was filling up amLog debug file.
095             */
096            Debug.error("LogRecord:LogRecord:SSOException: " + se.getMessage());
097        }
098    }
099
100    /**
101     * Constructor for auth logging
102     * @param level The log Level.
103     * @param msg The message string.
104     * @param properties The Hashtable containing the properties
105     *        for the LogRecord.
106     */
107
108    public LogRecord(Level level, String msg, Hashtable properties) {
109        this(level,msg);
110        String clientDomain = (String)properties.get(LogConstants.DOMAIN);
111        String clientID     = (String)properties.get(LogConstants.LOGIN_ID);
112        String ipAddress    = (String)properties.get(LogConstants.IP_ADDR); 
113        String loginIDSid   = (String)properties.get(LogConstants.LOGIN_ID_SID);
114        String moduleName   = (String)properties.get(LogConstants.MODULE_NAME);
115        String contextID    = (String)properties.get(LogConstants.CONTEXT_ID);
116        String messageID    = (String)properties.get(LogConstants.MESSAGE_ID);
117        String nameID       = (String)properties.get(LogConstants.NAME_ID);
118        String hostName = ipAddress;
119        if (ipAddress != null) {
120            try {
121                if (Logger.resolveHostName) {
122                    hostName =
123                        java.net.InetAddress.getByName(ipAddress).getHostName();
124                } else {
125                    hostName = ipAddress;
126                }
127            } catch (Exception e) {
128               Debug.error("LogRecord:LogRecord:Unable to get Host for:" +
129                   ipAddress);
130            }
131        }
132        Date date = newDate();
133        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
134        /*
135         * these are the compulsory fields ... to be logged even if there are
136         * exceptions while getting domain, loginid, ipaddr, hostname
137         */
138        addLogInfo(LogConstants.TIME, sdf.format(date));
139        addLogInfo(LogConstants.DATA, getMessage());
140        addLogInfo(LogConstants.LOG_LEVEL, getLevel().toString());
141        addLogInfo(LogConstants.DOMAIN, clientDomain);
142        addLogInfo(LogConstants.LOGIN_ID, clientID);
143        addLogInfo(LogConstants.IP_ADDR, ipAddress);
144        addLogInfo(LogConstants.HOST_NAME, hostName);
145        addLogInfo(LogConstants.LOGIN_ID_SID, loginIDSid);
146        addLogInfo(LogConstants.MODULE_NAME, moduleName);
147        /* if they're implemented... */
148        if ((messageID != null) && (messageID.length() > 0)) {
149            addLogInfo(LogConstants.MESSAGE_ID, messageID);
150        }
151        if ((contextID != null) && (contextID.length() > 0)) {
152            addLogInfo(LogConstants.CONTEXT_ID, contextID);
153        }
154        if ((nameID != null) && (nameID.length() > 0)) {
155            addLogInfo(LogConstants.NAME_ID, nameID);
156        }
157    }
158
159    /**
160     * Adds to the log information map, the field key and its corresponding
161     * value.
162     *
163     * @param key The key which will be used by the formatter to determine if
164     *        this piece of info is supposed to be added to the log string
165     *        according to the selected log fields.
166     * @param value The value which may form a part of the actual log-string.
167     * @supported.api
168     */
169    public void addLogInfo(String key,Object value) {
170        logInfoMap.put(key,value);
171    }
172    
173    /**
174     * Convenience method to set the log information map.
175     *
176     * @param logInfoMap Handler to the map which contains the log info
177     * @supported.api
178     */
179    public void setLogInfoMap(Map logInfoMap) {
180        this.logInfoMap = logInfoMap;
181    }
182    /**
183     * Returns the log information map which contains the set of fields and
184     * their corresponding values.
185     *
186     * @return The log information map.
187     * @supported.api
188     */
189    public Map getLogInfoMap() {
190        return logInfoMap;
191    }
192
193    /**
194     * Returns log by subject.
195     *
196     * @return log by subject.
197     */
198    public Object getLogBy() {
199        return null;
200    }
201
202    /**
203     * Returns log for subject.
204     *
205     * @return log for subject.
206     */
207    public Object getLogFor() {
208        return token;
209    }
210
211}