001    package railo.runtime.functions.system;
002    
003    import java.util.Iterator;
004    import java.util.Map;
005    import java.util.Map.Entry;
006    
007    import javax.servlet.http.HttpServletRequest;
008    
009    import railo.commons.io.SystemUtil;
010    import railo.commons.io.res.Resource;
011    import railo.commons.lang.SizeAndCount;
012    import railo.commons.lang.SizeAndCount.Size;
013    import railo.loader.engine.CFMLEngineFactory;
014    import railo.runtime.CFMLFactoryImpl;
015    import railo.runtime.Mapping;
016    import railo.runtime.MappingImpl;
017    import railo.runtime.PageContext;
018    import railo.runtime.PageContextImpl;
019    import railo.runtime.PageSourceImpl;
020    import railo.runtime.PageSourcePool;
021    import railo.runtime.config.ConfigImpl;
022    import railo.runtime.config.ConfigServer;
023    import railo.runtime.config.ConfigWeb;
024    import railo.runtime.config.ConfigWebImpl;
025    import railo.runtime.debug.ActiveLock;
026    import railo.runtime.debug.ActiveQuery;
027    import railo.runtime.engine.CFMLEngineImpl;
028    import railo.runtime.exp.PageException;
029    import railo.runtime.ext.function.Function;
030    import railo.runtime.lock.LockManager;
031    import railo.runtime.op.Caster;
032    import railo.runtime.type.Collection;
033    import railo.runtime.type.Collection.Key;
034    import railo.runtime.type.KeyImpl;
035    import railo.runtime.type.Query;
036    import railo.runtime.type.QueryImpl;
037    import railo.runtime.type.Struct;
038    import railo.runtime.type.StructImpl;
039    import railo.runtime.type.dt.DateTimeImpl;
040    import railo.runtime.type.scope.ScopeContext;
041    import railo.runtime.type.util.KeyConstants;
042    
043    public final class GetUsageData implements Function {
044        
045            private static final Key START_TIME = KeyImpl.init("starttime");
046            private static final Key CACHED_QUERIES = KeyImpl.init("cachedqueries");
047            private static final Key OPEN_CONNECTIONS = KeyImpl.init("openconnections");
048            private static final Key ELEMENTS = KeyImpl.init("elements");
049            private static final Key USERS = KeyImpl.init("users");
050            private static final Key QUERIES = KeyImpl.init("queries");
051            private static final Key LOCKS = KeyImpl.init("locks");
052            
053            public static Struct call(PageContext pc) throws PageException  {
054                    ConfigWeb cw = pc.getConfig();
055                    ConfigServer cs = cw.getConfigServer("server");
056                    ConfigWeb[] webs = cs.getConfigWebs();
057                    CFMLEngineFactory.getInstance();
058                    CFMLEngineImpl engine = (CFMLEngineImpl) cs.getCFMLEngine();
059                    
060                    Struct sct=new StructImpl();
061                    
062                    
063                    // Locks
064                    /*LockManager manager = pc.getConfig().getLockManager();
065            String[] locks = manager.getOpenLockNames();
066            for(int i=0;i<locks.length;i++){
067                    locks[i].
068            }
069            if(!ArrayUtil.isEmpty(locks)) 
070                    strLocks=" open locks at this time ("+List.arrayToList(locks, ", ")+").";
071                    */
072                    
073                    // Requests
074                    Query req=new QueryImpl(new Collection.Key[]{KeyConstants._web,KeyConstants._uri,START_TIME,KeyConstants._timeout}, 0, "requests");
075                    sct.setEL(KeyConstants._requests, req);
076                    
077                    // Template Cache
078                    Query tc=new QueryImpl(new Collection.Key[]{KeyConstants._web,ELEMENTS,KeyConstants._size}, 0, "templateCache");
079                    sct.setEL(KeyImpl.init("templateCache"), tc);
080                    
081                    // Scopes 
082                    Struct scopes=new StructImpl();
083                    sct.setEL(KeyConstants._scopes, scopes);
084                    Query app=new QueryImpl(new Collection.Key[]{KeyConstants._web,KeyConstants._application,ELEMENTS,KeyConstants._size}, 0, "templateCache");
085                    scopes.setEL(KeyConstants._application, app);
086                    Query sess=new QueryImpl(new Collection.Key[]{KeyConstants._web,KeyConstants._application,USERS,ELEMENTS,KeyConstants._size}, 0, "templateCache");
087                    scopes.setEL(KeyConstants._session, sess);
088    
089                    // Query
090                    Query qry=new QueryImpl(new Collection.Key[]{KeyConstants._web,KeyConstants._application,START_TIME,KeyConstants._sql}, 0, "requests");
091                    sct.setEL(QUERIES, qry);
092                    
093                    // Locks
094                    Query lck=new QueryImpl(new Collection.Key[]{KeyConstants._web,KeyConstants._application,KeyConstants._name,START_TIME,KeyConstants._timeout,KeyConstants._type}, 0, "requests");
095                    sct.setEL(LOCKS, lck);
096    
097                    // Loop webs
098                    ConfigWebImpl web;
099                    Struct pcs;
100                    PageContextImpl _pc;
101                    int row,openConnections=0;
102                    CFMLFactoryImpl factory;
103                    ActiveQuery[] queries;
104                    ActiveQuery aq;
105                    ActiveLock[] locks;
106                    ActiveLock al;
107                    for(int i=0;i<webs.length;i++){
108                            
109                            // Loop requests
110                            web=(ConfigWebImpl) webs[i];
111                            factory=(CFMLFactoryImpl)web.getFactory();
112                            pcs = factory.getRunningPageContextes();
113                            Iterator<Object> it = pcs.valueIterator();
114                            while(it.hasNext()){
115                                    _pc = (PageContextImpl) it.next();
116                                    if(_pc.isGatewayContext()) continue;
117                                    
118                                    // Request
119                                    row = req.addRow();
120                                    req.setAt(KeyConstants._web, row, web.getLabel());
121                                    req.setAt(KeyConstants._uri, row, getPath(_pc.getHttpServletRequest()));
122                                    req.setAt(START_TIME, row, new DateTimeImpl(pc.getStartTime(),false));
123                                    req.setAt(KeyConstants._timeout, row, new Double(pc.getRequestTimeout()));
124                                    
125                                    // Query
126                                    queries = _pc.getActiveQueries();
127                                    if(queries!=null) {
128                                            for(int y=0;y<queries.length;y++){
129                                                    aq=queries[y];
130                                                    row = qry.addRow();
131                                                    qry.setAt(KeyConstants._web, row, web.getLabel());
132                                                    qry.setAt(KeyConstants._application, row, _pc.getApplicationContext().getName());
133                                                    qry.setAt(START_TIME, row, new DateTimeImpl(web,aq.startTime,true));
134                                                    qry.setAt(KeyConstants._sql, row, aq.sql);
135                                            }
136                                    }
137                                    
138                                    // Lock
139                                    locks = _pc.getActiveLocks();
140                                    if(locks!=null) {
141                                            for(int y=0;y<locks.length;y++){
142                                                    al=locks[y];
143                                                    row = lck.addRow();
144                                                    lck.setAt(KeyConstants._web, row, web.getLabel());
145                                                    lck.setAt(KeyConstants._application, row, _pc.getApplicationContext().getName());
146                                                    lck.setAt(KeyConstants._name, row, al.name);
147                                                    lck.setAt(START_TIME, row, new DateTimeImpl(web,al.startTime,true));
148                                                    lck.setAt(KeyConstants._timeout, row, Caster.toDouble(al.timeoutInMillis/1000));
149                                                    lck.setAt(KeyConstants._type, row, al.type==LockManager.TYPE_EXCLUSIVE?"exclusive":"readonly");
150                                            }
151                                    }
152                            }
153                            openConnections+=web.getDatasourceConnectionPool().openConnections();
154    
155    
156                            // Template Cache
157                            Mapping[] mappings = ConfigImpl.getAllMappings(web);
158                            long[] tce = templateCacheElements(mappings);
159                            row = tc.addRow();
160                            tc.setAt(KeyConstants._web, row, web.getLabel());
161                            tc.setAt(KeyConstants._size, row, new Double(tce[1]));
162                            tc.setAt(ELEMENTS, row, new Double(tce[0]));
163                            
164                            // Scope Application
165                            getAllApplicationScopes(web,factory.getScopeContext(),app);
166                            getAllCFSessionScopes(web,factory.getScopeContext(),sess);
167                            
168                            
169                    }
170                    
171                    // Datasource
172                    Struct ds=new StructImpl();
173                    sct.setEL(KeyConstants._datasources, ds);
174                    ds.setEL(CACHED_QUERIES, Caster.toDouble(pc.getQueryCache().size(pc))); // there is only one cache for all contexts
175                    ds.setEL(OPEN_CONNECTIONS, Caster.toDouble(openConnections));
176                    
177                    // Memory
178                    Struct mem=new StructImpl();
179                    sct.setEL(KeyConstants._memory, mem);
180                    mem.setEL("heap", SystemUtil.getMemoryUsageAsStruct(SystemUtil.MEMORY_TYPE_HEAP));
181                    mem.setEL("nonheap", SystemUtil.getMemoryUsageAsStruct(SystemUtil.MEMORY_TYPE_NON_HEAP));
182                    
183                    
184                    // uptime
185                    sct.set("uptime", new DateTimeImpl(engine.uptime(),true));
186                    
187                    // now
188                    sct.set("now", new DateTimeImpl(pc));
189                    
190                    
191                    //SizeAndCount.Size size = SizeAndCount.sizeOf(pc.serverScope());
192                    
193                    
194                    
195                    return sct;
196        }
197            
198            private static void getAllApplicationScopes(ConfigWebImpl web, ScopeContext sc, Query app) throws PageException {
199                    Struct all = sc.getAllApplicationScopes();
200                    Iterator<Entry<Key, Object>> it = all.entryIterator();
201                    Entry<Key, Object> e;
202                    int row;
203                    Size sac;
204                    while(it.hasNext()){
205                            e = it.next();
206                            row=app.addRow();
207                            sac = SizeAndCount.sizeOf(e.getValue());
208                            app.setAt(KeyConstants._web, row, web.getLabel());
209                            app.setAt(KeyConstants._application, row, e.getKey().getString());
210                            app.setAt(KeyConstants._size, row, new Double(sac.size));
211                            app.setAt(ELEMENTS, row, new Double(sac.count));
212                            
213                    }
214            }
215            
216            private static void getAllCFSessionScopes(ConfigWebImpl web, ScopeContext sc, Query sess) throws PageException {
217                    Struct all = sc.getAllCFSessionScopes();
218                    Iterator it = all.entryIterator(),itt;
219                    Entry e,ee;
220                    int row,size,count,users;
221                    Size sac;
222                    // applications
223                    while(it.hasNext()){
224                            e = (Entry) it.next();
225                            itt = ((Map)e.getValue()).entrySet().iterator();
226                            size=0;count=0;users=0;
227                            while(itt.hasNext()){
228                                    ee=(Entry)itt.next();
229                                    sac = SizeAndCount.sizeOf(ee.getValue());
230                                    size+=sac.size;
231                                    count+=sac.count;
232                                    users++;
233                            }
234                            row=sess.addRow();
235                            
236                            sess.setAt(KeyConstants._web, row, web.getLabel());
237                            sess.setAt(USERS, row, new Double(users));
238                            sess.setAt(KeyConstants._application, row, e.getKey().toString());
239                            sess.setAt(KeyConstants._size, row, new Double(size));
240                            sess.setAt(ELEMENTS, row, new Double(count));
241                    }
242            }
243            
244            private static long[] templateCacheElements(Mapping[] mappings) {
245                    long elements=0,size=0;
246                    
247                    PageSourcePool psp;
248                    Object[] keys;
249                    PageSourceImpl ps;
250                    Resource res;
251                    MappingImpl mapping;
252                    for(int i=0;i<mappings.length;i++){
253                            mapping=(MappingImpl)mappings[i];
254                            psp = mapping.getPageSourcePool();
255                            keys = psp.keys();
256                            for(int y=0;y<keys.length;y++)       {
257                                    ps = (PageSourceImpl) psp.getPageSource(keys[y], false);
258                                    if(ps.isLoad()) {
259                                            elements++;
260                                            res=mapping.getClassRootDirectory().getRealResource(ps.getJavaName()+".class");
261                                            size+=res.length();
262                                    }
263                            }
264                    }
265                    return new long[]{elements,size};
266            }
267            
268            
269            public static String getScriptName(HttpServletRequest req) {
270                    return emptyIfNull(req.getContextPath())+emptyIfNull(req.getServletPath());
271            }
272    
273            public static String getPath(HttpServletRequest req) {
274                    String qs=emptyIfNull(req.getQueryString());
275                    if(qs.length()>0)qs="?"+qs;
276                            
277                            
278                    return emptyIfNull(req.getContextPath())+emptyIfNull(req.getServletPath())+qs;
279            }
280    
281            private static String emptyIfNull(String str) {
282                    if(str==null) return "";
283                    return str;
284            }
285    }