This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 56311
Collapse All | Expand All

(-)core/src/org/netbeans/core/CLIOptions.java (-10 lines)
Lines 186-201 public class CLIOptions extends CLIHandl Link Here
186
                }
186
                }
187
            }
187
            }
188
        }
188
        }
189
        
190
        if (!NonGui.noLogging) {
191
            try {
192
                NonGui.logger = new TopLogging(NonGui.getLogDir());
193
            } catch (IOException e) {
194
                System.err.println("Cannot create log file. Logging disabled."); // NOI18N
195
                e.printStackTrace();
196
            }
197
        }
198
        StartLog.logProgress("TopLogging initialized"); // NOI18N
199
    }
189
    }
200
    
190
    
201
    protected void usage(PrintWriter w) {
191
    protected void usage(PrintWriter w) {
(-)core/src/org/netbeans/core/Main.java (+16 lines)
Lines 303-308 public final class Main extends NonGui { Link Here
303
303
304
    CLIOptions.initialize();
304
    CLIOptions.initialize();
305
    StartLog.logProgress ("Command line parsed"); // NOI18N
305
    StartLog.logProgress ("Command line parsed"); // NOI18N
306
    
307
    {
308
        ByteArrayOutputStream bos = new ByteArrayOutputStream (4096);
309
        PrintStream ps = new PrintStream (bos);
310
        ps.println ();
311
        ps.println ("-----------------------------------------------------------------------------"); // NOI18N
312
        printSystemInfo(ps);
313
        ps.println ("-----------------------------------------------------------------------------"); // NOI18N
314
        ps.flush();
315
316
        try {
317
            ErrorManager.getDefault().log (ErrorManager.USER, bos.toString("utf-8")); // NOI18N
318
        } catch (UnsupportedEncodingException ex) {
319
            ex.printStackTrace();
320
        }
321
    }
306
322
307
// -----------------------------------------------------------------------------------------------------
323
// -----------------------------------------------------------------------------------------------------
308
// 4. Display Splash Screen & manager
324
// 4. Display Splash Screen & manager
(-)core/src/org/netbeans/core/NbErrorManager.java (-124 / +153 lines)
Lines 19-24 import java.lang.reflect.Field; Link Here
19
import java.lang.reflect.Method;
19
import java.lang.reflect.Method;
20
import java.io.*;
20
import java.io.*;
21
import java.util.*;
21
import java.util.*;
22
import java.util.logging.FileHandler;
23
import java.util.logging.Level;
24
import java.util.logging.Logger;
25
import java.util.logging.SimpleFormatter;
26
import java.util.logging.StreamHandler;
22
27
23
import org.xml.sax.SAXParseException;
28
import org.xml.sax.SAXParseException;
24
29
Lines 32-38 import org.openide.util.NbBundle; Link Here
32
public final class NbErrorManager extends ErrorManager {
37
public final class NbErrorManager extends ErrorManager {
33
38
34
    public NbErrorManager() {
39
    public NbErrorManager() {
35
        this(null, defaultSeverity(), null);
40
        this(null, null);
36
    }
41
    }
37
    
42
    
38
    /**
43
    /**
Lines 40-78 public final class NbErrorManager extend Link Here
40
     * @see "#18141"
45
     * @see "#18141"
41
     */
46
     */
42
    NbErrorManager(PrintStream pw) {
47
    NbErrorManager(PrintStream pw) {
43
        this(null, defaultSeverity(), pw);
48
        this(null, streamLogger (pw));
44
    }
49
    }
45
    
50
    
46
    private static int defaultSeverity() {
51
    private NbErrorManager(String pfx, Logger logger) {
47
        String dsev = System.getProperty("ErrorManager.minimum");
52
        if (logger == null) {
48
        // use e.g. 17 to avoid logging WARNING messages.
53
            if (pfx == null) {
49
        if (dsev != null) {
54
                pfx = ""; // NOI18N
50
            try {
51
                return Integer.parseInt(dsev);
52
            } catch (NumberFormatException nfe) {
53
                nfe.printStackTrace();
54
            }
55
        }
56
        // I.e. 2: avoid logging INFORMATIONAL messages.
57
        return ErrorManager.INFORMATIONAL + 1;
58
    }
59
    
60
    private NbErrorManager(String pfx, int sev, PrintStream pw) {
61
        prefix = pfx;
62
        minLogSeverity = sev;
63
        logWriter = pw;
64
        synchronized (uniquifiedIds) {
65
            Integer i = (Integer)uniquifiedIds.get(pfx);
66
            if (i == null) {
67
                uniquifier = 1;
68
            } else {
69
                uniquifier = i.intValue() + 1;
70
            }
55
            }
71
            uniquifiedIds.put(pfx, new Integer(uniquifier));
56
            logger = createLogger (pfx);
72
        }
57
        }
73
        //System.err.println("NbErrorManager[" + pfx + " #" + uniquifier + "]: minLogSeverity=" + sev);
58
        this.logger = logger;
74
    }
59
    }
75
60
61
    public void flush () {
62
        java.util.logging.Handler[] arr = logger.getHandlers();
63
        for (int i = 0; i < arr.length; i++) {
64
            arr[i].flush();
65
        }
66
    }
67
    
68
    private static Logger streamLogger (PrintStream pw) {
69
        Logger log = Logger.getAnonymousLogger();
70
        StreamHandler s = new StreamHandler (
71
            pw, NbFormater.FORMATTER
72
        );
73
        log.setLevel(Level.ALL);
74
        s.setLevel(Level.ALL);
75
        log.addHandler(s);
76
        return log;
77
    }
78
    
79
    private static java.util.logging.Handler streamHandler;
80
    private static synchronized java.util.logging.Handler streamHandler () {
81
        if (streamHandler == null) {
82
            streamHandler = new StreamHandler (System.err, NbFormater.FORMATTER);
83
        }
84
        return streamHandler;
85
    }
86
    
87
    private static java.util.logging.Handler defaultHandler;
88
    private static synchronized java.util.logging.Handler defaultHandler () {
89
        if (defaultHandler != null) return defaultHandler;
90
        
91
        String home = System.getProperty("netbeans.user");
92
        if (home != null && !NonGui.noLogging) {
93
            try {
94
                File f = new File (home + "/var/log");
95
                f.mkdirs ();
96
                
97
                defaultHandler = new FileHandler (home + "/var/log/messages.log", 1000000, 1, true);
98
                defaultHandler.setFormatter(NbFormater.FORMATTER);
99
            } catch (IOException ex) {
100
                ex.printStackTrace();
101
            }
102
        }
103
        
104
        if (defaultHandler == null) {
105
            defaultHandler = streamHandler();
106
        }
107
        return defaultHandler;
108
    }
109
    
110
    private static Logger createLogger (String pfx) {
111
        Logger logger = Logger.getLogger (pfx);
112
        logger.addHandler(defaultHandler ());
113
        if (Boolean.getBoolean("netbeans.logger.console")) { // NOI18N
114
            if (defaultHandler () instanceof FileHandler) {
115
                logger.addHandler (streamHandler ());
116
            }
117
        }
118
        return logger;
119
    }
120
    
76
    /** maps Throwables to java.util.List (Ann) */
121
    /** maps Throwables to java.util.List (Ann) */
77
    private static final Map map = new WeakHashMap (11);
122
    private static final Map map = new WeakHashMap (11);
78
    
123
    
Lines 82-126 public final class NbErrorManager extend Link Here
82
        java.util.Locale.ENGLISH
127
        java.util.Locale.ENGLISH
83
    );
128
    );
84
129
85
    /** The writer to the log file*/
130
    /** Where to log the file */
86
    private PrintStream logWriter;
131
    private Logger logger;
87
    
132
    
88
   /** assciates each thread with the lastly notified throwable
133
   /** assciates each thread with the lastly notified throwable
89
    * (Thread, Reference (Throwable))
134
    * (Thread, Reference (Throwable))
90
    */
135
    */
91
    private static final Map lastException = new WeakHashMap (27);
136
    private static final Map lastException = new WeakHashMap (27);
92
137
93
    /** Minimum value of severity to write message to the log file*/
94
    private final int minLogSeverity;
95
96
    /** Prefix preprended to customized loggers, if any. */
97
    private final String prefix;
98
    
99
    // Make sure two distinct EM impls log differently even with the same name.
100
    private final int uniquifier; // 0 for root EM (prefix == null), else >= 1
101
    private static final Map uniquifiedIds = new HashMap(20); // Map<String,Integer>
102
    
103
    static {
138
    static {
104
        System.setProperty("sun.awt.exception.handler", "org.netbeans.core.NbErrorManager$AWTHandler"); // NOI18N
139
        System.setProperty("sun.awt.exception.handler", "org.netbeans.core.NbErrorManager$AWTHandler"); // NOI18N
105
    }
140
    }
106
    
141
    
107
    /** Initializes the log stream.
108
     */
109
    private PrintStream getLogWriter () {
110
        synchronized (this) {
111
            if (logWriter != null) return logWriter;
112
        }
113
        
114
        PrintStream pw = TopLogging.getLogOutputStream();
115
        
116
        synchronized (this) {
117
            if (logWriter == null) {
118
                logWriter = pw;
119
            }
120
            return logWriter;
121
        }
122
    }
123
124
    public synchronized Throwable annotate (
142
    public synchronized Throwable annotate (
125
        Throwable t,
143
        Throwable t,
126
        int severity, String message, String localizedMessage,
144
        int severity, String message, String localizedMessage,
Lines 177-182 public final class NbErrorManager extend Link Here
177
    public boolean isNotifiable(int severity) {
195
    public boolean isNotifiable(int severity) {
178
        return isLoggable(severity + 1);
196
        return isLoggable(severity + 1);
179
    }
197
    }
198
    
199
    private static java.util.logging.Level mapSeverity (int severity) {
200
        if (severity == ErrorManager.UNKNOWN) {
201
            return Level.FINEST;
202
        }
203
        
204
        if (severity == ErrorManager.INFORMATIONAL) {
205
            return Level.FINE;
206
        }
207
        
208
        if (severity <= ErrorManager.WARNING) {
209
            return Level.WARNING;
210
        }
211
        
212
        if (severity <= ErrorManager.USER) {
213
            return Level.INFO;
214
        }
215
        
216
        if (severity <= ErrorManager.EXCEPTION) {
217
            return Level.INFO;
218
        }
219
        return Level.SEVERE;
220
    }
180
221
181
    /** Notifies all the exceptions associated with
222
    /** Notifies all the exceptions associated with
182
    * this thread.
223
    * this thread.
Lines 215-228 public final class NbErrorManager extend Link Here
215
            }
256
            }
216
        }
257
        }
217
        if (wantStackTrace) {
258
        if (wantStackTrace) {
218
            PrintStream log = getLogWriter();
259
            Level level = mapSeverity(ex.getSeverity ());
219
            if (prefix != null)
260
            if (logger.isLoggable(level)) {
220
                log.print ("[" + prefix + "] "); // NOI18N        
261
                String l = ex.getSeverity() == INFORMATIONAL ? "INFORMATIONAL " : "";// NOI18N
221
            String level = ex.getSeverity() == INFORMATIONAL ? "INFORMATIONAL " : "";// NOI18N
262
                String msg = EXC_HEADER.format (new Object[] { l, ex.getDate() });
222
            
263
                logger.log (level, msg);
223
            
264
                StringWriter w = new StringWriter ();
224
            log.println (EXC_HEADER.format (new Object[] { level, ex.getDate() }));
265
                ex.printStackTrace (new PrintWriter (w));
225
            ex.printStackTrace(log);
266
                msg = w.toString ();
267
                logger.log (level, msg);
268
            }
226
        }
269
        }
227
270
228
        if (ex.getSeverity () > INFORMATIONAL) {
271
        if (ex.getSeverity () > INFORMATIONAL) {
Lines 255-298 public final class NbErrorManager extend Link Here
255
    }
298
    }
256
299
257
    public void log(int severity, String s) {
300
    public void log(int severity, String s) {
258
        if (isLoggable (severity)) {
301
        logger.log (mapSeverity(severity), s);
259
            //System.err.println(toString() + " logging '" + s + "' at " + severity);
260
            PrintStream log = getLogWriter ();
261
            
262
            if (prefix != null) {
263
                boolean showUniquifier;
264
                // Print a unique EM sequence # if there is more than one
265
                // with this name. Shortcut: if the # > 1, clearly there are.
266
                if (uniquifier > 1) {
267
                    showUniquifier = true;
268
                } else if (uniquifier == 1) {
269
                    synchronized (uniquifiedIds) {
270
                        int count = ((Integer)uniquifiedIds.get(prefix)).intValue();
271
                        showUniquifier = count > 1;
272
                    }
273
                } else {
274
                    throw new IllegalStateException("prefix != null yet uniquifier == 0");
275
                }
276
                if (showUniquifier) {
277
                    log.print ("[" + prefix + " #" + uniquifier + "] "); // NOI18N
278
                } else {
279
                    log.print ("[" + prefix + "] "); // NOI18N
280
                }
281
            }
282
            log.println(s);
283
        }
284
    }
302
    }
285
    
303
    
286
    /** Allows to test whether messages with given severity will be logged
287
     * or not prior to constraction of complicated and time expensive
288
     * logging messages.
289
     *
290
     * @param severity the severity to check
291
     * @return false if the next call to log method with the same severity will
292
     *    discard the message
293
     */
294
    public boolean isLoggable (int severity) {
304
    public boolean isLoggable (int severity) {
295
        return severity >= minLogSeverity;
305
        return logger.isLoggable (mapSeverity(severity));
296
    }
306
    }
297
    
307
    
298
    
308
    
Lines 301-329 public final class NbErrorManager extend Link Here
301
     * a hierarchy.
311
     * a hierarchy.
302
     */
312
     */
303
    public final ErrorManager getInstance(String name) {
313
    public final ErrorManager getInstance(String name) {
304
        String pfx = (prefix == null) ? name : prefix + '.' + name;
314
        String pfx = logger.getName() + '.' + name;
305
        int sev = minLogSeverity;
315
        return new NbErrorManager(pfx, null);
306
        String prop = pfx;
307
        while (prop != null) {
308
            String value = System.getProperty (prop);
309
            //System.err.println ("Trying; prop=" + prop + " value=" + value);
310
            if (value != null) {
311
                try {
312
                    sev = Integer.parseInt (value);                    
313
                } catch (NumberFormatException nfe) {
314
                    notify (WARNING, nfe);
315
                }
316
                break;
317
            } else {
318
                int idx = prop.lastIndexOf ('.');
319
                if (idx == -1)
320
                    prop = null;
321
                else
322
                    prop = prop.substring (0, idx);
323
            }
324
        }
325
        //System.err.println ("getInstance: prefix=" + prefix + " mls=" + minLogSeverity + " name=" + name + " prefix2=" + newEM.prefix + " mls2=" + newEM.minLogSeverity);
326
        return new NbErrorManager(pfx, sev, logWriter);
327
    }    
316
    }    
328
    
317
    
329
    /** Method (or field) names in various exception classes which give
318
    /** Method (or field) names in various exception classes which give
Lines 474-480 public final class NbErrorManager extend Link Here
474
    }
463
    }
475
    
464
    
476
    public String toString() {
465
    public String toString() {
477
        return super.toString() + "<" + prefix + "," + minLogSeverity + ">"; // NOI18N
466
        return super.toString() + "<" + logger + ">"; // NOI18N
478
    }
467
    }
479
468
480
    /** Implementation of annotation interface.
469
    /** Implementation of annotation interface.
Lines 849-852 public final class NbErrorManager extend Link Here
849
            ErrorManager.getDefault().notify((ERROR << 1), t);
838
            ErrorManager.getDefault().notify((ERROR << 1), t);
850
        }
839
        }
851
    }
840
    }
841
842
    /** Modified formater for use in NetBeans.
843
     */
844
    private static final class NbFormater extends java.util.logging.Formatter {
845
        private static String lineSeparator = System.getProperty ("line.separator"); // NOI18N
846
        static java.util.logging.Formatter FORMATTER = new NbFormater ();
847
848
        
849
        public String format(java.util.logging.LogRecord record) {
850
            StringBuffer sb = new StringBuffer();
851
            sb.append(record.getLevel().getLocalizedName());
852
            addLoggerName (sb, record);
853
            sb.append(": ");
854
            String message = formatMessage(record);
855
            sb.append(message);
856
            sb.append(lineSeparator);
857
            if (record.getThrown() != null) {
858
                try {
859
                    StringWriter sw = new StringWriter();
860
                    PrintWriter pw = new PrintWriter(sw);
861
                    record.getThrown().printStackTrace(pw);
862
                    pw.close();
863
                    sb.append(sw.toString());
864
                } catch (Exception ex) {
865
                }
866
            }
867
            return sb.toString();
868
        }
869
        
870
        private static void addLoggerName (StringBuffer sb, java.util.logging.LogRecord record) {
871
            String name = record.getLoggerName ();
872
            if (!"".equals (name)) {
873
                if (record.getSourceClassName() != null) {	
874
                    sb.append(record.getSourceClassName());
875
                } else {
876
                    sb.append(record.getLoggerName());
877
                }
878
            }
879
        }
880
    }    
852
}
881
}
(-)core/src/org/netbeans/core/NbTopManager.java (+62 lines)
Lines 26-31 import java.text.MessageFormat; Link Here
26
import java.util.List;
26
import java.util.List;
27
import java.util.Locale;
27
import java.util.Locale;
28
import java.util.Map;
28
import java.util.Map;
29
import java.util.StringTokenizer;
29
import javax.swing.*;
30
import javax.swing.*;
30
import javax.swing.border.*;
31
import javax.swing.border.*;
31
import javax.swing.event.ChangeEvent;
32
import javax.swing.event.ChangeEvent;
Lines 170-175 public abstract class NbTopManager { Link Here
170
            }
171
            }
171
        }
172
        }
172
    }
173
    }
174
    
175
    /** Prints system information into print stream.
176
     */
177
    static void printSystemInfo(PrintStream ps) {
178
        String buildNumber = System.getProperty ("netbeans.buildnumber"); // NOI18N
179
        String currentVersion = NbBundle.getMessage(NbTopManager.class, "currentVersion", buildNumber );
180
        ps.println("  Product Version       = " + currentVersion); // NOI18N
181
        ps.println("  Operating System      = " + System.getProperty("os.name", "unknown")
182
                   + " version " + System.getProperty("os.version", "unknown")
183
                   + " running on " +  System.getProperty("os.arch", "unknown"));
184
        ps.println("  Java; VM; Vendor      = " + System.getProperty("java.version", "unknown") + "; " +
185
                   System.getProperty("java.vm.name", "unknown") + " " + System.getProperty("java.vm.version", "") + "; " +
186
                   System.getProperty("java.vendor", "unknown"));
187
        //ps.println("  Java Vendor URL          = " + System.getProperty("java.vendor.url", "unknown"));
188
        ps.println("  Java Home             = " + System.getProperty("java.home", "unknown"));
189
        //ps.println("  Java Class Version       = " + System.getProperty("java.class.version", "unknown"));
190
        ps.print  ("  System Locale; Encod. = " + Locale.getDefault()); // NOI18N
191
        String branding = NbBundle.getBranding ();
192
        if (branding != null) {
193
            ps.print(" (" + branding + ")"); // NOI18N
194
        }
195
        ps.println("; " + System.getProperty("file.encoding", "unknown")); // NOI18N
196
        ps.println("  Home Dir; Current Dir = " + System.getProperty("user.home", "unknown") + "; " +
197
                   System.getProperty("user.dir", "unknown"));
198
        ps.println("  IDE Install; User Dir = " + Main.getHomeDir () + "; " + // NOI18N
199
                   Main.getUserDir ()); // NOI18N
200
        //ps.println("  System Directory         = " + Main.getSystemDir ()); // NOI18N
201
        ps.println("  CLASSPATH             = " + System.getProperty("java.class.path", "unknown")); // NOI18N
202
        ps.println("  Boot & ext classpath  = " + createBootClassPath()); // NOI18N
203
        ps.println("  Dynamic classpath     = " + System.getProperty("netbeans.dynamic.classpath", "unknown")); // NOI18N
204
    }
205
206
    // Copied from NbClassPath:
207
    private static String createBootClassPath() {
208
        // boot
209
        String boot = System.getProperty("sun.boot.class.path"); // NOI18N
210
        StringBuffer sb = (boot != null ? new StringBuffer(boot) : new StringBuffer());
211
        
212
        // std extensions
213
        String extensions = System.getProperty("java.ext.dirs"); // NOI18N
214
        if (extensions != null) {
215
            for (StringTokenizer st = new StringTokenizer(extensions, File.pathSeparator); st.hasMoreTokens();) {
216
                File dir = new File(st.nextToken());
217
                File[] entries = dir.listFiles();
218
                if (entries != null) {
219
                    for (int i = 0; i < entries.length; i++) {
220
                        String name = entries[i].getName().toLowerCase(Locale.US);
221
                        if (name.endsWith(".zip") || name.endsWith(".jar")) { // NOI18N
222
                            if (sb.length() > 0) {
223
                                sb.append(File.pathSeparatorChar);
224
                            }
225
                            sb.append(entries[i].getPath());
226
                        }
227
                    }
228
                }
229
            }
230
        }
231
        
232
        return sb.toString();
233
    }
234
    
173
235
174
    /** Constructs a new manager.
236
    /** Constructs a new manager.
175
    */
237
    */
(-)core/src/org/netbeans/core/NonGui.java (-3 lines)
Lines 77-85 public class NonGui extends NbTopManager Link Here
77
    /** The flag whether to show the Splash screen on the startup */
77
    /** The flag whether to show the Splash screen on the startup */
78
    protected static boolean noSplash = false;
78
    protected static boolean noSplash = false;
79
79
80
    /** The Class that logs the IDE events to a log file */
81
    protected static TopLogging logger;
82
    
83
    /** Tests need to clear some static variables.
80
    /** Tests need to clear some static variables.
84
     */
81
     */
85
    static final void clearForTests () {
82
    static final void clearForTests () {
(-)core/src/org/netbeans/core/NonGuiMain.java (-1 / +1 lines)
Lines 87-93 public class NonGuiMain extends NonGui { Link Here
87
        String sysInfo;
87
        String sysInfo;
88
        sysInfo = NbBundle.getBundle(org.netbeans.core.NonGui.class).getString ("CTL_System_info");	// NOI18N
88
        sysInfo = NbBundle.getBundle(org.netbeans.core.NonGui.class).getString ("CTL_System_info");	// NOI18N
89
        out.println("-- " + sysInfo + " ----------------------------------------------------------------"); // NOI18N
89
        out.println("-- " + sysInfo + " ----------------------------------------------------------------"); // NOI18N
90
        org.netbeans.core.TopLogging.printSystemInfo(out);
90
        printSystemInfo(out);
91
        out.println("-------------------------------------------------------------------------------"); // NOI18N
91
        out.println("-------------------------------------------------------------------------------"); // NOI18N
92
    }
92
    }
93
    
93
    
(-)core/src/org/netbeans/core/TopLogging.java (-287 lines)
Removed Link Here
1
/*
2
 *                 Sun Public License Notice
3
 * 
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 * 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.core;
15
16
import java.io.*;
17
import java.text.DateFormat;
18
import java.util.Locale;
19
import java.util.StringTokenizer;
20
21
import org.openide.util.NbBundle;
22
import org.openide.util.RequestProcessor;
23
24
/**
25
 * A class that provides logging facility for the IDE - once instantiated, it
26
 * redirects the System.err into a log file.
27
 * @author Ian Formanek, Ales Novak, Jesse Glick
28
 */
29
public class TopLogging
30
{
31
    /** The name of the log file */
32
    public static final String LOG_FILE_NAME = "messages.log"; // NOI18N
33
34
    private static final boolean disabledConsole = ! Boolean.getBoolean("netbeans.logger.console"); // NOI18N
35
36
    private final PrintStream logPrintStream;
37
38
    private static TopLogging topLogging;
39
    
40
    /** Maximal size of log file.*/
41
    private static final long LOG_MAX_SIZE = 
42
        Long.getLong("org.netbeans.core.TopLogging.LOG_MAX_SIZE", 0x40000).longValue(); // NOI18N
43
44
    /** Number of old log files that are maintained.*/    
45
    private static final int LOG_COUNT = 
46
        Integer.getInteger("org.netbeans.core.TopLogging.LOG_COUNT", 3).intValue(); // NOI18N
47
    
48
    
49
    /** Creates a new TopLogging - redirects the System.err to a log file.
50
     * @param logDir A directory for the log file
51
     */
52
    TopLogging (String logDir) throws IOException  {
53
        topLogging = this;
54
        
55
        File logFileDir = new File (logDir);
56
        if (! logFileDir.exists () && ! logFileDir.mkdirs ()) {
57
            throw new IOException ("Cannot make directory to contain log file"); // NOI18N
58
        }
59
        File logFile = createLogFile (logFileDir, LOG_FILE_NAME);
60
        if ((logFile.exists() && !logFile.canWrite()) || logFile.isDirectory()) {
61
            throw new IOException ("Cannot write to file"); // NOI18N
62
        }
63
64
        OutputStream log = new BufferedOutputStream(new FileOutputStream(logFile.getAbsolutePath(), true));
65
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH);
66
        java.util.Date date = new java.util.Date();
67
68
        final PrintStream stderr = System.err;
69
        logPrintStream = new PrintStream(new StreamDemultiplexor(stderr, log), false, "UTF-8"); // NOI18N
70
        Runtime.getRuntime().addShutdownHook(new Thread() {
71
            public void run() {
72
                logPrintStream.flush(); // #31519
73
                logPrintStream.close();
74
            }
75
        });
76
        logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N
77
        logPrintStream.println(">Log Session: "+ df.format (date)); // NOI18N
78
        logPrintStream.println(">System Info: "); // NOI18N
79
        printSystemInfo(logPrintStream);
80
        logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N
81
82
        System.setErr(logPrintStream);
83
    }
84
85
    private static TopLogging getDefault() {
86
        if (topLogging == null) {
87
            try {
88
                new TopLogging(NonGui.getLogDir());
89
            } catch (IOException x) {
90
                org.openide.ErrorManager.getDefault().notify(x);
91
            }
92
        }
93
        return topLogging;
94
    }
95
96
    /** This method limits size of log files. There is kept: actual log file   
97
     *  and old log files. This method prevents from growing log file infinitely.*/
98
    private static File createLogFile (File parent, String chld) {
99
        long firstModified = 0;
100
        File renameTo = null;
101
        File retFile = new File (parent, chld);
102
        
103
        if (!retFile.exists() || retFile.length() < LOG_MAX_SIZE)
104
            return retFile;
105
        
106
        for (int i = 1; i < LOG_COUNT;i++) {
107
            String logName = chld + "."+i; // NOI18N
108
            File logFile = new File (parent, logName);
109
            
110
            if (!logFile.exists()) {
111
                renameTo = logFile;               
112
                break;
113
            }
114
            
115
            long logModif = logFile.lastModified();
116
            if ((firstModified == 0 || logModif < firstModified) &&  logModif > 0) {
117
                firstModified = logModif;
118
                renameTo = logFile;
119
            }            
120
        }
121
122
        if (renameTo != null) {
123
            if (renameTo.exists()) renameTo.delete();
124
            retFile.renameTo(renameTo);
125
        }
126
        
127
        return retFile;
128
    }
129
    
130
    public static void printSystemInfo(PrintStream ps) {
131
        String buildNumber = System.getProperty ("netbeans.buildnumber"); // NOI18N
132
        String currentVersion = NbBundle.getMessage(TopLogging.class, "currentVersion", buildNumber );
133
        ps.println("  Product Version       = " + currentVersion); // NOI18N
134
        ps.println("  Operating System      = " + System.getProperty("os.name", "unknown")
135
                   + " version " + System.getProperty("os.version", "unknown")
136
                   + " running on " +  System.getProperty("os.arch", "unknown"));
137
        ps.println("  Java; VM; Vendor      = " + System.getProperty("java.version", "unknown") + "; " +
138
                   System.getProperty("java.vm.name", "unknown") + " " + System.getProperty("java.vm.version", "") + "; " +
139
                   System.getProperty("java.vendor", "unknown"));
140
        //ps.println("  Java Vendor URL          = " + System.getProperty("java.vendor.url", "unknown"));
141
        ps.println("  Java Home             = " + System.getProperty("java.home", "unknown"));
142
        //ps.println("  Java Class Version       = " + System.getProperty("java.class.version", "unknown"));
143
        ps.print  ("  System Locale; Encod. = " + Locale.getDefault()); // NOI18N
144
        String branding = NbBundle.getBranding ();
145
        if (branding != null) {
146
            ps.print(" (" + branding + ")"); // NOI18N
147
        }
148
        ps.println("; " + System.getProperty("file.encoding", "unknown")); // NOI18N
149
        ps.println("  Home Dir; Current Dir = " + System.getProperty("user.home", "unknown") + "; " +
150
                   System.getProperty("user.dir", "unknown"));
151
        ps.println("  IDE Install; User Dir = " + Main.getHomeDir () + "; " + // NOI18N
152
                   Main.getUserDir ()); // NOI18N
153
        //ps.println("  System Directory         = " + Main.getSystemDir ()); // NOI18N
154
        ps.println("  CLASSPATH             = " + System.getProperty("java.class.path", "unknown")); // NOI18N
155
        ps.println("  Boot & ext classpath  = " + createBootClassPath()); // NOI18N
156
        ps.println("  Dynamic classpath     = " + System.getProperty("netbeans.dynamic.classpath", "unknown")); // NOI18N
157
    }
158
159
    // Copied from NbClassPath:
160
    private static String createBootClassPath() {
161
        // boot
162
        String boot = System.getProperty("sun.boot.class.path"); // NOI18N
163
        StringBuffer sb = (boot != null ? new StringBuffer(boot) : new StringBuffer());
164
        
165
        // std extensions
166
        String extensions = System.getProperty("java.ext.dirs"); // NOI18N
167
        if (extensions != null) {
168
            for (StringTokenizer st = new StringTokenizer(extensions, File.pathSeparator); st.hasMoreTokens();) {
169
                File dir = new File(st.nextToken());
170
                File[] entries = dir.listFiles();
171
                if (entries != null) {
172
                    for (int i = 0; i < entries.length; i++) {
173
                        String name = entries[i].getName().toLowerCase(Locale.US);
174
                        if (name.endsWith(".zip") || name.endsWith(".jar")) { // NOI18N
175
                            if (sb.length() > 0) {
176
                                sb.append(File.pathSeparatorChar);
177
                            }
178
                            sb.append(entries[i].getPath());
179
                        }
180
                    }
181
                }
182
            }
183
        }
184
        
185
        return sb.toString();
186
    }
187
    
188
    protected void finalize() throws Throwable {
189
        logPrintStream.flush();
190
        logPrintStream.close();
191
    }
192
193
    static PrintStream getLogOutputStream() {
194
        if (System.getProperty("netbeans.user") == null) { // NOI18N
195
            // No user directory. E.g. from <makeparserdb>. Skip ide.log.
196
            return System.err;
197
        }
198
        return TopLogging.getDefault().logPrintStream;
199
    }
200
201
    private static final class StreamDemultiplexor extends OutputStream implements Runnable {
202
        
203
        /** task to flush the log file, or null */
204
        private RequestProcessor.Task logFlushTask;
205
206
        /** processor in which to flush them */
207
        private static final RequestProcessor RP = new RequestProcessor("Flush ide.log"); // NOI18N
208
209
        /** a lock for flushing */
210
        private static final Object FLUSH_LOCK = new String("org.netbeans.core.TopLogging.StreamDemultiplexor.FLUSH_LOCK"); // NOI18N
211
212
        /** delay for flushing */
213
        private static final int FLUSH_DELAY = Integer.getInteger("netbeans.logger.flush.delay", 15000).intValue(); // NOI18N
214
215
        private final OutputStream stderr;
216
        private final OutputStream log;
217
218
        StreamDemultiplexor(PrintStream stderr, OutputStream log) {
219
            this.stderr = stderr;
220
            this.log = log;
221
        }
222
        
223
        public void write(int b) throws IOException {
224
            log.write(b);
225
            if (! disabledConsole)
226
                stderr.write(b);
227
            flushLog();
228
        }
229
230
        public void write(byte b[]) throws IOException {
231
            log.write(b);
232
            if (! disabledConsole) stderr.write(b);
233
            flushLog();
234
        }
235
236
        public void write(byte b[],
237
                          int off,
238
                          int len)
239
        throws IOException {
240
            log.write(b, off, len);
241
            if (! disabledConsole) stderr.write(b, off, len);
242
            flushLog();
243
        }
244
245
        public void flush() throws IOException {
246
            log.flush();
247
            stderr.flush();
248
        }
249
250
        public void close() throws IOException {
251
            log.close();
252
            stderr.close();
253
        }
254
255
        /**
256
         * Flush the log file asynch.
257
         * Waits for e.g. 15 seconds after the first write.
258
         * Note that this is only a delay to force a flush; if there is a lot
259
         * of content, the buffer will fill up and it may have been written out
260
         * long before. This just catches any trailing content.
261
         * @see "#31519"
262
         */
263
        private void flushLog() {
264
            synchronized (FLUSH_LOCK) {
265
                if (logFlushTask == null) {
266
                    logFlushTask = RP.create(this);
267
                    logFlushTask.schedule(FLUSH_DELAY);
268
                }
269
            }
270
        }
271
272
        /**
273
         * Flush log messages periodically.
274
         */
275
        public void run() {
276
            synchronized (FLUSH_LOCK) {
277
                try {
278
                    flush();
279
                } catch (IOException e) {
280
                    e.printStackTrace();
281
                }
282
                logFlushTask = null;
283
            }
284
        }
285
286
    }
287
}
(-)core/src/org/netbeans/core/modules/NbEvents.java (-11 / +13 lines)
Lines 18-23 package org.netbeans.core.modules; Link Here
18
import java.io.File;
18
import java.io.File;
19
import java.text.Collator;
19
import java.text.Collator;
20
import java.util.*;
20
import java.util.*;
21
import java.util.logging.Level;
22
import java.util.logging.Logger;
21
import org.openide.awt.StatusDisplayer;
23
import org.openide.awt.StatusDisplayer;
22
import org.openide.NotifyDescriptor;
24
import org.openide.NotifyDescriptor;
23
import org.openide.ErrorManager;
25
import org.openide.ErrorManager;
Lines 76-82 final class NbEvents extends Events { Link Here
76
        } else if (message == FINISH_ENABLE_MODULES) {
78
        } else if (message == FINISH_ENABLE_MODULES) {
77
            List modules = (List)args[0];
79
            List modules = (List)args[0];
78
            if (! modules.isEmpty()) {
80
            if (! modules.isEmpty()) {
79
                System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_finish_enable_modules"));
81
                Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_finish_enable_modules"));
80
                dumpModulesList(modules);
82
                dumpModulesList(modules);
81
            }
83
            }
82
            StatusDisplayer.getDefault().setStatusText(
84
            StatusDisplayer.getDefault().setStatusText(
Lines 129-135 final class NbEvents extends Events { Link Here
129
            }
131
            }
130
            String msg = buf.toString();
132
            String msg = buf.toString();
131
            notify(msg, true);
133
            notify(msg, true);
132
            System.err.println(msg);
134
            Logger.getLogger("").log (Level.WARNING, msg);
133
            StatusDisplayer.getDefault().setStatusText("");
135
            StatusDisplayer.getDefault().setStatusText("");
134
        } else if (message == FAILED_INSTALL_NEW_UNEXPECTED) {
136
        } else if (message == FAILED_INSTALL_NEW_UNEXPECTED) {
135
            Module m = (Module)args[0];
137
            Module m = (Module)args[0];
Lines 150-156 final class NbEvents extends Events { Link Here
150
                throw new IllegalStateException("Module " + m + " could not be installed but had no problems"); // NOI18N
152
                throw new IllegalStateException("Module " + m + " could not be installed but had no problems"); // NOI18N
151
            }
153
            }
152
            notify(buf.toString(), true);
154
            notify(buf.toString(), true);
153
            System.err.println(buf.toString());
155
            Logger.getLogger("").log (Level.WARNING, buf.toString());
154
            StatusDisplayer.getDefault().setStatusText("");
156
            StatusDisplayer.getDefault().setStatusText("");
155
        } else if (message == START_READ) {
157
        } else if (message == START_READ) {
156
            StatusDisplayer.getDefault().setStatusText(
158
            StatusDisplayer.getDefault().setStatusText(
Lines 176-187 final class NbEvents extends Events { Link Here
176
            // Nice to see the real title; not that common, after all.
178
            // Nice to see the real title; not that common, after all.
177
            StatusDisplayer.getDefault().setStatusText(
179
            StatusDisplayer.getDefault().setStatusText(
178
                NbBundle.getMessage(NbEvents.class, "MSG_install", ((Module)args[0]).getDisplayName()));
180
                NbBundle.getMessage(NbEvents.class, "MSG_install", ((Module)args[0]).getDisplayName()));
179
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_install", ((Module)args[0]).getDisplayName()));
181
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_install", ((Module)args[0]).getDisplayName()));
180
            Main.incrementSplashProgressBar();
182
            Main.incrementSplashProgressBar();
181
        } else if (message == UPDATE) {
183
        } else if (message == UPDATE) {
182
            StatusDisplayer.getDefault().setStatusText(
184
            StatusDisplayer.getDefault().setStatusText(
183
                NbBundle.getMessage(NbEvents.class, "MSG_update", ((Module)args[0]).getDisplayName()));
185
                NbBundle.getMessage(NbEvents.class, "MSG_update", ((Module)args[0]).getDisplayName()));
184
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_update", ((Module)args[0]).getDisplayName()));
186
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_update", ((Module)args[0]).getDisplayName()));
185
            Main.incrementSplashProgressBar();
187
            Main.incrementSplashProgressBar();
186
        } else if (message == UNINSTALL) {
188
        } else if (message == UNINSTALL) {
187
            StatusDisplayer.getDefault().setStatusText(
189
            StatusDisplayer.getDefault().setStatusText(
Lines 211-220 final class NbEvents extends Events { Link Here
211
            Util.err.log(ErrorManager.WARNING, "Warning: the extension " + (File)args[0] + " may be multiply loaded by modules: " + (Set/*<File>*/)args[1] + "; see: http://www.netbeans.org/download/dev/javadoc/OpenAPIs/org/openide/doc-files/classpath.html#class-path"); // NOI18N
213
            Util.err.log(ErrorManager.WARNING, "Warning: the extension " + (File)args[0] + " may be multiply loaded by modules: " + (Set/*<File>*/)args[1] + "; see: http://www.netbeans.org/download/dev/javadoc/OpenAPIs/org/openide/doc-files/classpath.html#class-path"); // NOI18N
212
        } else if (message == MISSING_JAR_FILE) {
214
        } else if (message == MISSING_JAR_FILE) {
213
            File jar = (File)args[0];
215
            File jar = (File)args[0];
214
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_missing_jar_file", jar.getAbsolutePath()));
216
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_missing_jar_file", jar.getAbsolutePath()));
215
        } else if (message == CANT_DELETE_ENABLED_AUTOLOAD) {
217
        } else if (message == CANT_DELETE_ENABLED_AUTOLOAD) {
216
            Module m = (Module)args[0];
218
            Module m = (Module)args[0];
217
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_cant_delete_enabled_autoload", m.getDisplayName()));
219
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_cant_delete_enabled_autoload", m.getDisplayName()));
218
        } else if (message == MISC_PROP_MISMATCH) {
220
        } else if (message == MISC_PROP_MISMATCH) {
219
            // XXX does this really need to be logged to the user?
221
            // XXX does this really need to be logged to the user?
220
            // Or should it just be sent quietly to the log file?
222
            // Or should it just be sent quietly to the log file?
Lines 222-231 final class NbEvents extends Events { Link Here
222
            String prop = (String)args[1];
224
            String prop = (String)args[1];
223
            Object onDisk = (Object)args[2];
225
            Object onDisk = (Object)args[2];
224
            Object inMem = (Object)args[3];
226
            Object inMem = (Object)args[3];
225
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_misc_prop_mismatch", new Object[] {m.getDisplayName(), prop, onDisk, inMem}));
227
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_misc_prop_mismatch", new Object[] {m.getDisplayName(), prop, onDisk, inMem}));
226
        } else if (message == PATCH) {
228
        } else if (message == PATCH) {
227
            File f = (File)args[0];
229
            File f = (File)args[0];
228
            System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_patch", f.getAbsolutePath()));
230
            Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_patch", f.getAbsolutePath()));
229
        }
231
        }
230
        // XXX other messages?
232
        // XXX other messages?
231
    }
233
    }
Lines 261-273 final class NbEvents extends Events { Link Here
261
            // #32331: use platform-specific newlines
263
            // #32331: use platform-specific newlines
262
            buf.append(lineSep);
264
            buf.append(lineSep);
263
        }
265
        }
264
        System.err.print(buf.toString());
266
        Logger.getLogger("").log (Level.INFO, buf.toString());
265
    }
267
    }
266
    
268
    
267
    private void notify(String text, boolean warn) {
269
    private void notify(String text, boolean warn) {
268
        if (Boolean.getBoolean("netbeans.full.hack")) { // NOI18N
270
        if (Boolean.getBoolean("netbeans.full.hack")) { // NOI18N
269
            // #21773: interferes with automated GUI testing.
271
            // #21773: interferes with automated GUI testing.
270
            System.err.println(text);
272
            Logger.getLogger("").log (Level.INFO, text);
271
        } else {
273
        } else {
272
            // Normal - display dialog.
274
            // Normal - display dialog.
273
            int type = warn ? NotifyDescriptor.WARNING_MESSAGE : NotifyDescriptor.INFORMATION_MESSAGE;
275
            int type = warn ? NotifyDescriptor.WARNING_MESSAGE : NotifyDescriptor.INFORMATION_MESSAGE;
(-)core/src/org/netbeans/core/ui/ProductInformationPanel.java (-3 / +1 lines)
Lines 27-34 import javax.swing.JPanel; Link Here
27
27
28
import org.openide.util.NbBundle;
28
import org.openide.util.NbBundle;
29
29
30
import org.netbeans.core.TopLogging;
31
32
30
33
public class ProductInformationPanel extends JPanel {
31
public class ProductInformationPanel extends JPanel {
34
32
Lines 418-424 public class ProductInformationPanel ext Link Here
418
        return new MessageFormat(
416
        return new MessageFormat(
419
                NbBundle.getBundle("org.netbeans.core.Bundle", // NOI18N
417
                NbBundle.getBundle("org.netbeans.core.Bundle", // NOI18N
420
                                   Locale.getDefault(),
418
                                   Locale.getDefault(),
421
                                   TopLogging.class.getClassLoader()
419
                                   ProductInformationPanel.class.getClassLoader()
422
                ).getString("currentVersion")
420
                ).getString("currentVersion")
423
            ).format(
421
            ).format(
424
                new Object[] {
422
                new Object[] {
(-)core/test/unit/src/org/netbeans/core/NbErrorManagerTest.java (-4 / +24 lines)
Lines 40-51 public class NbErrorManagerTest extends Link Here
40
    private NbErrorManager err;
40
    private NbErrorManager err;
41
    private ByteArrayOutputStream w;
41
    private ByteArrayOutputStream w;
42
    protected void setUp() throws Exception {
42
    protected void setUp() throws Exception {
43
        w = new ByteArrayOutputStream();
43
        clearWorkDir();
44
        System.setProperty("netbeans.user", getWorkDirPath());
45
        
46
        w = new ByteArrayOutputStream() {
47
            public String toString () {
48
                err.flush();
49
                return super.toString ();
50
            }
51
        };
44
        err = new NbErrorManager(new PrintStream(w));
52
        err = new NbErrorManager(new PrintStream(w));
45
    }
53
    }
46
    
54
    
47
    public void testEMFound() throws Exception {
55
    public void testEMFound() throws Exception {
48
        assertEquals(NbErrorManager.class, Lookup.getDefault().lookup(ErrorManager.class).getClass());
56
        ErrorManager em = (ErrorManager)Lookup.getDefault ().lookup (ErrorManager.class);
57
        assertNotNull ("em", em);
58
        assertEquals(NbErrorManager.class, em.getClass());
59
        
60
        em.log (em.EXCEPTION, "Exception!");
61
        
62
        File f = new File (new File (new File (getWorkDirPath (), "var"), "log"), "messages.log");
63
        if (!f.exists ()) {
64
            fail (
65
                "Cannot find messages.log, parent contains just: " + 
66
                java.util.Arrays.asList (f.getParentFile().list())
67
            );
68
        }
49
    }
69
    }
50
    
70
    
51
    public void testBasicNotify() throws Exception {
71
    public void testBasicNotify() throws Exception {
Lines 56-62 public class NbErrorManagerTest extends Link Here
56
        assertTrue(s.indexOf("java.lang.NullPointerException: unloc msg") != -1);
76
        assertTrue(s.indexOf("java.lang.NullPointerException: unloc msg") != -1);
57
        assertTrue(s.indexOf("testBasicNotify") != -1);
77
        assertTrue(s.indexOf("testBasicNotify") != -1);
58
    }
78
    }
59
    
79
/*    
60
    public void testLog() throws Exception {
80
    public void testLog() throws Exception {
61
        assertFalse(err.isLoggable(ErrorManager.INFORMATIONAL));
81
        assertFalse(err.isLoggable(ErrorManager.INFORMATIONAL));
62
        err.log("some msg");
82
        err.log("some msg");
Lines 79-85 public class NbErrorManagerTest extends Link Here
79
        assertTrue(s.indexOf("sub msg #2") != -1);
99
        assertTrue(s.indexOf("sub msg #2") != -1);
80
        assertTrue(s.indexOf("quux.hoho.yaya") != -1);
100
        assertTrue(s.indexOf("quux.hoho.yaya") != -1);
81
    }
101
    }
82
    
102
*/    
83
    /** @see "#15611" */
103
    /** @see "#15611" */
84
    public void testNestedThrowables() throws Exception {
104
    public void testNestedThrowables() throws Exception {
85
        NullPointerException npe = new NullPointerException("unloc msg");
105
        NullPointerException npe = new NullPointerException("unloc msg");

Return to bug 56311