Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Posts: 777
Registered: ‎07-21-2012
My Device: 9810
My Carrier: 0

How to create own log File

Hello 

 

Can we make our own log file , ?

 

If tell me how to make own log file.

Developer
Posts: 17,012
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport
My Carrier: O2 Germany

Re: How to create own log File

the easy solution is to use the built-in Logger class, but that means that the logs will only be available in the device log (alt+lglg).
We build our own logger service that logs to Logger, sysout and the persistant store, with a listview as UI and some tools to send the logfile as an attachment to your own or another mail address.

there are also some RIM-developed logger tools, i think the BIS push sample (not the simplified which i wrote) contains a logfactory or somesuch, but it should not be very difficult to write something that fits your needs.
----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: How to create own log File

The Facebook SDK implements one of the more common open source Logging class, have a look at it too. 

 

There is also a much simpler Logging class included in the tutorial samples here:

http://supportforums.blackberry.com/t5/Java-Development/Tutorials-for-new-developers-Part-1/m-p/1621...

Developer
Posts: 777
Registered: ‎07-21-2012
My Device: 9810
My Carrier: 0

Re: How to create own log File

//#preprocess

import net.rim.device.api.system.ApplicationDescriptor;
import net.rim.device.api.system.EventLogger;
import net.rim.device.api.util.StringUtilities;

import java.util.Vector;

public class XLogger {
    private static final long GUID = StringUtilities.stringHashToLong(ApplicationDescriptor.currentApplicationDescriptor().getModuleName());
    private static String xLoggerToken = "XLG";

    public static final int DATALOSS = 1; //F%$%)#!!!!
    public static final int FATAL_ERROR = 2; //SUPER BAD
    public static final int ERROR = 4; //Really bad
    public static final int WARNING = 8; //Bad
    public static final int INFO = 16; //Okay...

    public static int MAX_SIZE = 400;
    public static final boolean LOGGING_ON = true;

    protected static XLogger instance;

    private Vector log;

    public static XLogger getInstance() {
        if (instance == null) {
            instance = (XLogger) RuntimeSingletonFactory.getSingletonInstance(new RuntimeConstructorDelegate() {
                public Object create() {
                    return new XLogger();
                }
            });
        }
        
        //This is for a test commit to see if tracker is linked to github
        return instance;
    }
    


    public static void setXLoggerToken(String token) {
        xLoggerToken = token;
    }

    protected XLogger() {
        log = new Vector();
        String name = EventLogger.getRegisteredAppName(GUID);
        if (name == null || !name.equalsIgnoreCase(xLoggerToken)) {
            EventLogger.register(GUID, xLoggerToken, EventLogger.VIEWER_STRING);
        }
    }


    public static void resetLog() {
        XLogger.getInstance().log = new Vector();
    }

    public static void dataloss(Class cls, Exception e) {
        XLogger.dataloss(cls, "Exception: " + e.toString());
    }

    public static void dataloss(Class cls, String msg) {

        //#ifdef ANALYTICS
        //   com.flurry.blackberry.FlurryAgent.onError("DATALOSS", msg, cls.getName());
        //#endif
        XLogger.getInstance().log(cls, DATALOSS, msg);
    }

    public static void fatal(Class cls, Exception e) {
        XLogger.fatal(cls, "Exception: " + e.toString());
    }

    public static void fatal(Class cls, String msg) {
        //#ifdef ANALYTICS
        //    com.flurry.blackberry.FlurryAgent.onError("FATAL", msg, cls.getName());
        //#endif
        XLogger.getInstance().log(cls, FATAL_ERROR, msg);
    }

    public static void error(Class cls, Exception e) {
        XLogger.error(cls, "Exception: " + e.toString());
    }

    public static void error(Class cls, String msg) {
        //#ifdef ANALYTICS
        //    com.flurry.blackberry.FlurryAgent.onError("ERROR", msg, cls.getName());
        //#endif
        XLogger.getInstance().log(cls, ERROR, msg);
    }

    public static void warn(Class cls, Exception e) {
        XLogger.warn(cls, "Exception: " + e.toString());
    }

    public static void warn(Class cls, String msg) {
        XLogger.getInstance().log(cls, WARNING, msg);
    }

    public static void info(Class cls, Exception e) {
        XLogger.info(cls, "Exception: " + e.toString());
    }

    public static void info(Class cls, String msg) {
        XLogger.getInstance().log(cls, INFO, msg);
    }

    public Vector dumpLog() {
        return log;
    }

    public Vector dumpFilteredLog(int flags) {

        Vector ret = new Vector();

        for (int i = 0; i < log.size(); i++) {
            LogEntry curr = (LogEntry) log.elementAt(i);

            if ((flags & curr.level) != 0) {
                ret.addElement(curr);
            }
        }

        return ret;
    }

    public void log(Class cls, int level, String msg) {

        if (log.size() >= MAX_SIZE) {
            log.removeElementAt(0);
        }

        String fullClassPath = cls.getName();
        String className = fullClassPath.substring(fullClassPath.lastIndexOf('.') + 1, fullClassPath.length());
        LogEntry entry = new LogEntry(System.currentTimeMillis(), className, level, msg);
        log.addElement(entry);
        systemLog(level, entry);
    }

    private void systemLog(int level, LogEntry entry) {
        if(!LOGGING_ON) {
            return;
        }
        
        //#ifdef DEVELOPMENT
        if (level == ERROR || level == FATAL_ERROR || level == DATALOSS) {
            System.err.println(entry);
        } else {
            System.out.println(entry);
        }
        //#endif
        switch (level) {
            case INFO:
                //#ifdef DEVELOPMENT
                EventLogger.logEvent(GUID, entry.toString().getBytes(), EventLogger.DEBUG_INFO);
                //#endif
                break;
            case WARNING:
                EventLogger.logEvent(GUID, entry.toString().getBytes(), EventLogger.WARNING);
            case FATAL_ERROR:
                EventLogger.logEvent(GUID, entry.toString().getBytes(), EventLogger.SEVERE_ERROR);
                break;
            case ERROR:
                EventLogger.logEvent(GUID, entry.toString().getBytes(), EventLogger.ERROR);
                break;
            default:
                EventLogger.logEvent(GUID, entry.toString().getBytes(), EventLogger.ALWAYS_LOG);
                break;
        }
    }

    private String levelToString(int level) {

        switch (level) {
            case DATALOSS:
                return "DATALOSS";
            case FATAL_ERROR:
                return "FATAL";
            case ERROR:
                return "ERROR";
            case WARNING:
                return "WARN";
            case INFO:
                return "INFO";
        }

        return "UNKNOWN";
    }

    private class LogEntry {
        public String msg;
        public int level;
        public String cls;
        public long date;

        public LogEntry(long date, String cls, int level, String msg) {
            this.date = date;
            this.cls = cls;
            this.level = level;
            this.msg = msg;
        }

        public String toString() {
            StringBuffer logMsg = new StringBuffer();
            logMsg = logMsg.append(levelToString(level)).append(" ").append(date).append(" ").append(msg).append("\t").append(cls);
            return logMsg.toString();
        }
    }

    public String getLogBlob(int flags) {

        Vector log = dumpFilteredLog(flags);
        StringBuffer ret = new StringBuffer();

        for (int i = 0; i < log.size(); i++) {
            ret = ret.append(log.elementAt(i).toString()).append("\n");
        }

        return ret.toString();
    }
}

 ***************************************************

package com.telus.mobileworker.applicationloader;
 
import net.rim.device.api.system.CodeModuleManager;
import net.rim.device.api.util.StringUtilities;
 
public abstract class RuntimeConstructorDelegate {
    public abstract Object create();
 
    protected long getGuid() {
        return StringUtilities.stringHashToLong(new StringBuffer(getClass().getName())
                .append(CodeModuleManager.getModuleHandleForClass(getClass()))
                .toString());
    }
}
 
 **********************************************************
import net.rim.device.api.system.CodeModuleManager;
import net.rim.device.api.system.ControlledAccessException;
import net.rim.device.api.system.RuntimeStore;
import net.rim.device.api.util.StringUtilities;


public class RuntimeSingletonFactory {
    private static Object storeLock = getStoreLock();

    /**
     * A fatal error thrown from any of the static methods methods
     */
    public static class Disaster extends RuntimeException {
        public Disaster(String message) {
            super(message);
        }
    }

    protected interface StoreOperation {
        public Object run(RuntimeStore store);
    }

    /**
     * Synchronization on the store object itself may blocks all other processes synchronizing on the store object and
     * causes system instability.  Realistically, we only need synchronization on the singlton objects themselves not the
     * entire store.
     *
     * @return
     */
    private static Object getStoreLock() {
        if (storeLock == null) {
            long id = 0xedc3fe77439aaca9L; //com.xtremelabs.xtremeutil.util.RuntimeSingletonFactory converted by JDE to long
            final RuntimeStore store = RuntimeStore.getRuntimeStore();
            storeLock = store.get(id);
            if (storeLock == null) {
                storeLock = new Object();
                store.replace(id, storeLock);
            }
        }
        return storeLock;
    }

    /**
     * Helper method to perform a synchronized operation on the runtime store. The global
     * store object is locked and then passed to the <code>run</code> method of the given
     * <code>StoreOperation</code>.
     *
     * @param block passed the global RuntimeStore, which will be locked for the duration
     * @param klass contextual class, used only for error messages
     * @return the value returned from the block
     */
    protected static Object withStore(StoreOperation block, Class klass) {
        try {
            final RuntimeStore store = RuntimeStore.getRuntimeStore();
            synchronized (storeLock) {
                return block.run(store);
            }
        } catch (ControlledAccessException ex) {
            error(klass, ex, "not authorized to access runtime store");
        }
        return null; // unreachable
    }

    /**
     * Helper method to handle fatal errors (by throwing an informative Disaster exception)
     *
     * @param klass   a class related to the original exception
     * @param ex      the original exception
     * @param message a specific message related to the error condition
     * @throws Disaster always
     */
    protected static void error(Class klass, Exception ex, String message) throws Disaster {
        String text = new StringBuffer("Failed to construct/return the singleton object.")
                .append("\nReference class: ").append(klass.getName())
                .append("\nReference message: ").append(message)
                .append("\nReference exception: ").append(ex).toString();
        if (klass != XLogger.class) {
            XLogger.fatal(RuntimeSingletonFactory.class, text);
        }
        throw new Disaster(text);
    }


    /**
     * Create or return the existing global singleton for the given class delegated by the RuntimeConstructorDelegate object
     *
     * @param delegate constructs the base instance of the global singleton and is used to generate the runtime store id
     * @return the singular instance of the given class
     * @throws IllegalArgumentException if the given instance is <code>null</code>
     */
    public static Object getSingletonInstance(final RuntimeConstructorDelegate delegate) {
        final long id = delegate.getGuid();
        return withStore(new StoreOperation() {
            public Object run(RuntimeStore store) {
                Object o = store.get(id);
                if (o == null) {
                    o = delegate.create();
                    if (o == null) {
                        throw new IllegalArgumentException("global singleton instance can't be null");
                    }
                    try {
                        store.put(id, o);
                    } catch (IllegalArgumentException e) {
                        Object oldObj = store.replace(id, o);
                        if (o.getClass() != XLogger.class) {
                            XLogger.warn(RuntimeSingletonFactory.class,
                                    new StringBuffer("replacing existing instance of wrong class: ")
                                            .append(oldObj.getClass().getName())
                                            .append(" with new class: ")
                                            .append(o.getClass().getName())
                                            .toString());
                        }
                    }
                }
                return o;
            }
        }, delegate.getClass());
    }

    /**
     * Explicitly set the global singleton instance for a class.
     *
     * @param delegate constructs the base instance of the global singleton and is used to generate the runtime store id
     * @throws IllegalArgumentException if the given instance is <code>null</code>
     * @throws IllegalStateException    if there is already a global singleton instance for the given class
     */
    public static void setSingletonInstance(final RuntimeConstructorDelegate delegate) {
        final Object instance = delegate.create();
        if (instance == null) {
            throw new IllegalArgumentException("global singleton instance can't be null");
        }
        final long id = delegate.getGuid();

        withStore(new StoreOperation() {
            public Object run(RuntimeStore store) {
                Object existing = store.get(id);
                if (existing == null) {
                    store.put(id, instance);
                } else if (existing != instance) {
                    throw new IllegalStateException("a different global singleton already exists for the given class");
                }
                return null;
            }
        }, instance.getClass());
    }


    /**
     * Removes the global singleton for the given class and returns it
     *
     * @param delegate for which to remove the global singleton
     * @return the former global instance or <code>null</code> if none existed for the given class
     */
    public static Object removeSingletonInstance(RuntimeConstructorDelegate delegate) {
        if (delegate == null) {
            XLogger.warn(RuntimeSingletonFactory.class, "could not remove singlton instance, delegate was null");
            return null;
        }
        final long id = delegate.getGuid();
        return withStore(new StoreOperation() {
            public Object run(RuntimeStore store) {
                return store.remove(id);
            }
        }, delegate.getClass());
    }

    /**
     * Return the existing global singleton for the given class, or <code>null</code> if
     * there is no global singleton for the class.
     *
     * @param delegate for which to remove the global singleton
     * @return the global singleton instance for the given class
     */
    public static Object getExistingSingletonInstance(final RuntimeConstructorDelegate delegate) {
        return withStore(new StoreOperation() {
            public Object run(RuntimeStore store) {
                return store.get(delegate.getGuid());
            }
        }, delegate.getClass());
    }

    /**
     * Return a long GUID for the given class, using the name of the class
     * and the handle of its module (the name alone is NOT unique as multiple
     * modules can contain classes with the same name).
     *
     * @param klass to be used for id generation
     * @return runtime id used for the class
     * @deprecated Use com.xtremelabs.xtremeutil.RuntimeConstructorDelegate.getGuid() instead
     */
    protected static long getRuntimeId(Class klass) {
        return StringUtilities.stringHashToLong(new StringBuffer()
                .append(klass.getName())
                .append(CodeModuleManager.getModuleHandleForClass(klass))
                .toString());
    }

    /**
     * Helper method to dynamically instantiate a class. Errors are rethrown
     * as a Disaster with an informative message.
     *
     * @param klass class to instantiate
     * @return new instance of the class
     * @throws Disaster if instantiation fails
     * @deprecated
     */
    protected static Object instantiate(Class klass) throws Disaster {
        try {
            return klass.newInstance();
        } catch (IllegalAccessException ex) {
            error(klass, ex, "no accessible default constructor");
        } catch (InstantiationException ex) {
            error(klass, ex, "class is not instantiable");
        } catch (Exception ex) {
            error(klass, ex, "unknown failure");
        }
        return null; // unreachable
    }

    /**
     * Create or return the existing global singleton for the given class
     *
     * @param klass class of the global singleton
     * @return the singular instance of the given class
     * @deprecated Use com.xtremelabs.xtremeutil.RuntimeSingletonFactory.getSingletonInstance(RuntimeConstructorDelegate delegate) instead
     */
    public static Object getSingletonInstance(final Class klass) {
        final long id = getRuntimeId(klass);
        return withStore(new StoreOperation() {
            public Object run(RuntimeStore store) {
                Object o = store.get(id);
                if (o == null) {
                    o = instantiate(klass);
                    store.put(id, o);
                } else if (!klass.isInstance(o)) {
                    if (klass != XLogger.class) {
                        XLogger.warn(RuntimeSingletonFactory.class, "replacing existing instance of wrong class: " +
                                o.getClass().getName());
                    }
                    o = instantiate(klass);
                    store.replace(id, o);
                }
                return o;
            }
        }, klass);
    }

}

 I am using like this

 

XLogger.error(LandingNew_2Class.class, "dgdfg");

 

But i want to write log in SdCard or in internal memory how to do that?

i want to save a text file to make a log which is save in Sdcard.if user can read that log able to read that

Highlighted
Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: How to create own log File

I am not sure what the problem is here.  You have to do this yourself, but it is simply a matter of creating a file and writing to it. 

 

Personally to avoid the overhead I would not log to SD Card all the time - how often do you actually need the log?  You could give the user the option to turn logging on to recover a log for you, or alternatively, log to memory and copy to SD Card when you want to get the log.

 

If you want the user to send you the log file, then they can email it - in fact I think the tutorial example I pointed you to does exactly that.  In my experience, users struggle to even do that so whatever mechanism you are looking at, make it easy for users to supply it to you.