001    package railo.runtime.tag;
002    
003    import java.io.IOException;
004    
005    import railo.commons.io.log.LogConsole;
006    import railo.commons.io.log.LogResource;
007    import railo.commons.io.res.Resource;
008    import railo.commons.lang.StringUtil;
009    import railo.runtime.config.Config;
010    import railo.runtime.exp.ApplicationException;
011    import railo.runtime.exp.PageException;
012    import railo.runtime.ext.tag.TagImpl;
013    import railo.runtime.op.Caster;
014    import railo.runtime.tag.util.DeprecatedUtil;
015    
016    /**
017    * Writes a message to a log file.
018    *
019    *
020    *
021    **/
022    public final class Log extends TagImpl {
023    
024        private final static short LOG_APPLICATION=10;
025        private final static short LOG_SCHEDULER=11;
026        private final static short LOG_CONSOLE=12;
027        
028        
029    
030            /** If you omit the file attribute, specifies the standard log file in which to write the message. 
031            **              Ignored if you specify a file attribute */
032            private short log=LOG_APPLICATION;
033    
034            /** The message text to log. */
035            private String text;
036    
037            /** The type or severity of the message. */
038            private short type=railo.commons.io.log.Log.LEVEL_INFO;
039            /**  */
040            private String file;
041    
042            /** Specifies whether to log the application name if one has been specified in a application tag. */
043            private boolean application;
044            private String charset=null;
045            
046            @Override
047            public void release()   {
048                    super.release();
049                    log=LOG_APPLICATION;
050                    type=railo.commons.io.log.Log.LEVEL_INFO;
051                    file=null;
052                    application=false;
053                    charset=null;
054            }
055    
056            /** set the value log
057            *  If you omit the file attribute, specifies the standard log file in which to write the message. 
058            *               Ignored if you specify a file attribute
059            * @param log value to set
060             * @throws ApplicationException
061            **/
062            public void setLog(String log) throws ApplicationException      {
063                    if(StringUtil.isEmpty(log,true)) return;
064                log=log.toLowerCase().trim();
065                if(log.equals("application")) this.log=LOG_APPLICATION;
066                else if(log.equals("scheduler")) this.log=LOG_SCHEDULER;
067                else if(log.equals("console")) this.log=LOG_CONSOLE;
068                    else 
069                        throw new ApplicationException("invalid value for attribute log ["+log+"]","valid values are [application, scheduler,console]");
070            }
071    
072            /** set the value text
073            *  The message text to log.
074            * @param text value to set
075            **/
076            public void setText(String text)        {
077                    this.text=text;
078            }
079    
080            /** set the value type
081            *  The type or severity of the message.
082            * @param type value to set
083             * @throws ApplicationException
084            **/
085            public void setType(String type) throws ApplicationException    {
086                type=type.toLowerCase().trim(); 
087                if(type.equals("information")) this.type=railo.commons.io.log.Log.LEVEL_INFO;
088                else if(type.equals("info")) this.type=railo.commons.io.log.Log.LEVEL_INFO;
089                else if(type.equals("warning")) this.type=railo.commons.io.log.Log.LEVEL_WARN;
090                else if(type.equals("warn")) this.type=railo.commons.io.log.Log.LEVEL_WARN;
091                else if(type.equals("error")) this.type=railo.commons.io.log.Log.LEVEL_ERROR;
092            else if(type.startsWith("fatal")) this.type=railo.commons.io.log.Log.LEVEL_FATAL;
093            else if(type.startsWith("debug")) this.type=railo.commons.io.log.Log.LEVEL_DEBUG;
094                    else
095                        throw new ApplicationException("invalid value for attribute type ["+type+"]",
096                          "valid values are [information,warning,error,fatal,debug]");
097    
098            }
099    
100            /** set the value time
101            *  Specifies whether to log the system time.
102            * @param time value to set
103             * @throws ApplicationException
104            **/
105            public void setTime(boolean useTime) throws ApplicationException        {
106                    if(useTime) return;
107                    DeprecatedUtil.tagAttribute(pageContext,"Log", "time");
108                throw new ApplicationException("attribute [time] for tag [log] is deprecated, only the value true is allowed");
109            }
110    
111            /** set the value file
112            *  
113            * @param file value to set
114             * @throws ApplicationException
115            **/
116            public void setFile(String file) throws ApplicationException    {
117                    if(StringUtil.isEmpty(file))return;
118                    
119                if(file.indexOf('/')!=-1 || file.indexOf('\\')!=-1)
120                    throw new ApplicationException("value ["+file+"] from attribute [file] at tag [log] can only contain a filename, file separators like [\\/] are not allowed");
121                    if(!file.endsWith(".log"))file+=".log";
122                    this.file=file;
123            }
124    
125            /** set the value date
126            *  Specifies whether to log the system date.
127            * @param date value to set
128             * @throws ApplicationException
129            **/
130            public void setDate(boolean useDate) throws ApplicationException        {
131                    if(useDate) return;
132                    DeprecatedUtil.tagAttribute(pageContext,"Log", "date");
133                throw new ApplicationException("attribute [date] for tag [log] is deprecated, only the value true is allowed");
134            }
135    
136            /** set the value thread
137            *  Specifies whether to log the thread ID. The thread ID identifies which internal service thread logged a 
138            *               message. Since a service thread normally services a CFML page request to completion, then moves on to 
139            *               the next queued request, the thread ID serves as a rough indication of which request logged a message. 
140            *               Leaving thread IDs turned on can help diagnose patterns of server activity.
141            * @param thread value to set
142             * @throws ApplicationException
143            **/
144            public void setThread(boolean thread) throws ApplicationException       {
145                    if(thread) return;
146                    DeprecatedUtil.tagAttribute(pageContext,"Log", "thread");
147                throw new ApplicationException("attribute [thread] for tag [log] is deprecated, only the value true is allowed");
148            }
149    
150            /** set the value application
151            *  Specifies whether to log the application name if one has been specified in a application tag.
152            * @param application value to set
153            **/
154            public void setApplication(boolean application) {
155                    this.application=application;
156            }
157    
158    
159            @Override
160            public int doStartTag() throws PageException    {
161                railo.commons.io.log.Log logger;
162                Config config =pageContext.getConfig();
163                if(file==null) {
164                    if(log==LOG_SCHEDULER)logger=config.getScheduleLogger();
165                    else if(log==LOG_CONSOLE)logger=LogConsole.getInstance(config, railo.commons.io.log.Log.LEVEL_INFO);
166                    else logger=config.getApplicationLogger();
167                    
168                }
169                else {
170                    if(charset==null) charset=pageContext.getConfig().getResourceCharset();
171                    Resource logDir=config.getConfigDir().getRealResource("logs");
172                    if(!logDir.exists())logDir.mkdirs();
173                    try {
174                            Resource f = logDir.getRealResource(file);
175                    logger=new LogResource(f,railo.commons.io.log.Log.LEVEL_INFO,charset);
176                } catch (IOException e) {
177                    throw Caster.toPageException(e);
178                }
179                }
180                
181                
182                String contextName = pageContext.getApplicationContext().getName();
183                if(contextName==null || !application)contextName="";
184                logger.log(type,contextName,text);
185            //logger.write(toStringType(type),contextName,text);
186                    return SKIP_BODY;
187            }
188    
189            /**
190             * @param charset the charset to set
191             */
192            public void setCharset(String charset) {
193                    if(StringUtil.isEmpty(log,true)) return;
194                this.charset = charset;
195            }
196    }