001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.engine; 020 021import java.io.IOException; 022import java.nio.charset.Charset; 023import java.util.ArrayList; 024import java.util.Iterator; 025import java.util.Map; 026 027import javax.servlet.http.HttpServletRequest; 028 029import lucee.commons.io.IOUtil; 030import lucee.commons.io.res.Resource; 031import lucee.commons.io.res.util.ResourceUtil; 032import lucee.commons.lang.ExceptionUtil; 033import lucee.commons.lang.StringUtil; 034import lucee.commons.lang.SystemOut; 035import lucee.runtime.PageContext; 036import lucee.runtime.functions.other.CreateUUID; 037import lucee.runtime.op.Caster; 038 039public class ResourceExecutionLog extends ExecutionLogSupport { 040 041 private static int count=1; 042 private Resource file; 043 private StringBuffer content; 044 private PageContext pc; 045 private StringBuffer header; 046 private ArrayList<String> pathes=new ArrayList<String>(); 047 private long start; 048 private Resource dir; 049 050 051 protected void _init(PageContext pc, Map<String, String> arguments) { 052 this.pc=pc; 053 054 //header 055 HttpServletRequest req = pc.getHttpServletRequest(); 056 057 header=new StringBuffer(); 058 createHeader(header,"context-path",req.getContextPath()); 059 createHeader(header,"remote-user",req.getRemoteUser()); 060 createHeader(header,"remote-addr",req.getRemoteAddr()); 061 createHeader(header,"remote-host",req.getRemoteHost()); 062 createHeader(header,"script-name",StringUtil.emptyIfNull(req.getContextPath())+StringUtil.emptyIfNull(req.getServletPath())); 063 createHeader(header,"server-name",req.getServerName()); 064 createHeader(header,"protocol",req.getProtocol()); 065 createHeader(header,"server-port",Caster.toString(req.getServerPort())); 066 createHeader(header,"path-info",StringUtil.replace( 067 StringUtil.emptyIfNull(req.getRequestURI()), 068 StringUtil.emptyIfNull(req.getServletPath()),"", true)); 069 //createHeader(header,"path-translated",pc.getBasePageSource().getDisplayPath()); 070 createHeader(header,"query-string",req.getQueryString()); 071 createHeader(header,"unit",unitShortToString(unit)); 072 createHeader(header,"min-time-nano",min+""); 073 074 content=new StringBuffer(); 075 076 077 // directory 078 String strDirectory=arguments.get("directory"); 079 if(dir==null) { 080 if(StringUtil.isEmpty(strDirectory)) { 081 dir=getTemp(pc); 082 } 083 else { 084 try { 085 dir = ResourceUtil.toResourceNotExisting(pc, strDirectory,false,false); 086 if(!dir.exists()){ 087 dir.createDirectory(true); 088 } 089 else if(dir.isFile()){ 090 err(pc,"can not create directory ["+dir+"], there is already a file with same name."); 091 } 092 } 093 catch (Throwable t) { 094 ExceptionUtil.rethrowIfNecessary(t); 095 err(pc,t); 096 dir=getTemp(pc); 097 } 098 } 099 } 100 file=dir.getRealResource((pc.getId())+"-"+CreateUUID.call(pc)+".exl"); 101 file.createNewFile(); 102 start=System.currentTimeMillis(); 103 } 104 105 private static Resource getTemp(PageContext pc) { 106 Resource tmp = pc.getConfig().getConfigDir(); 107 Resource dir = tmp.getRealResource("execution-log"); 108 if(!dir.exists())dir.mkdirs(); 109 return dir; 110 } 111 112 protected void _release() { 113 114 // execution time 115 createHeader(header, "execution-time", Caster.toString(System.currentTimeMillis()-start)); 116 header.append("\n"); 117 118 119 //path 120 StringBuilder sb=new StringBuilder(); 121 Iterator<String> it = pathes.iterator(); 122 int count=0; 123 while(it.hasNext()){ 124 sb.append(count++); 125 sb.append(":"); 126 sb.append(it.next()); 127 sb.append("\n"); 128 } 129 sb.append("\n"); 130 try { 131 IOUtil.write(file, header+sb.toString()+content.toString(), (Charset)null, false); 132 } catch (IOException ioe) { 133 err(pc,ioe); 134 } 135 } 136 137 private void createHeader(StringBuffer sb,String name, String value) { 138 sb.append(name); 139 sb.append(":"); 140 sb.append(StringUtil.emptyIfNull(value)); 141 sb.append("\n"); 142 } 143 144 145 146 @Override 147 protected void _log(int startPos, int endPos, long startTime, long endTime) { 148 long diff=endTime-startTime; 149 if(unit==UNIT_MICRO)diff/=1000; 150 else if(unit==UNIT_MILLI)diff/=1000000; 151 152 content.append(path(pc.getCurrentPageSource().getDisplayPath())); 153 content.append("\t"); 154 content.append(startPos); 155 content.append("\t"); 156 content.append(endPos); 157 content.append("\t"); 158 content.append(diff); 159 content.append("\n"); 160 } 161 162 163 private int path(String path) { 164 int index= pathes.indexOf(path); 165 if(index==-1){ 166 pathes.add(path); 167 return pathes.size()-1; 168 } 169 return index; 170 } 171 172 private void err(PageContext pc, String msg) { 173 SystemOut.print(pc.getConfig().getErrWriter(), msg); 174 } 175 176 private void err(PageContext pc, Throwable t) { 177 String msg =ExceptionUtil.getStacktrace(t,true); 178 SystemOut.print(pc.getConfig().getErrWriter(), msg); 179 } 180}