/* * Copyright 2015 the original author or authors. * @https://github.com/scouter-project/scouter * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package scouter.agent.trace; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import scouter.agent.netio.data.DataProxy; import scouter.lang.step.ApiCallStep; import scouter.lang.step.ApiCallSum; import scouter.lang.step.MethodStep; import scouter.lang.step.MethodSum; import scouter.lang.step.SocketStep; import scouter.lang.step.SocketSum; import scouter.lang.step.SqlStep; import scouter.lang.step.SqlSum; import scouter.lang.step.Step; import scouter.lang.step.StepEnum; import scouter.lang.step.StepSingle; import scouter.util.IntKeyMap; import scouter.util.LongKeyMap; public class ProfileSummary implements IProfileCollector { private TraceContext context; protected IntKeyMap<Step> methods; protected IntKeyMap<Step> sqls; protected IntKeyMap<Step> apicalls; protected LongKeyMap<Step> sockets; protected int magindex = 0; protected int totalCount; public ProfileSummary(TraceContext context) { this.context = context; } protected void process() { List<Step> steps = new ArrayList<Step>(totalCount); toArray(methods, steps); toArray(sqls, steps); toArray(apicalls, steps); toArray(sockets, steps); totalCount = 0; DataProxy.sendProfile(steps, context); } private void toArray(IntKeyMap<Step> src, List<Step> out) { if (src == null) return; Enumeration<Step> en = src.values(); for (int i = 0, max = src.size(); i < max; i++) { out.add(en.nextElement()); } src.clear(); } private void toArray(LongKeyMap<Step> src, List<Step> out) { if (src == null) return; Enumeration<Step> en = src.values(); for (int i = 0, max = src.size(); i < max; i++) { out.add(en.nextElement()); } src.clear(); } private void toArray(List<Step> src, List<Step> out) { if (src == null) return; for (int i = 0, max = src.size(); i < max; i++) { out.add(src.get(i)); } src.clear(); } public void push(StepSingle ss) { } public void add(StepSingle ss) { switch (ss.getStepType()) { case StepEnum.METHOD: add((MethodStep) ss); break; case StepEnum.SQL: add((SqlStep) ss); break; case StepEnum.APICALL: add((ApiCallStep) ss); break; case StepEnum.SOCKET: add((SocketStep) ss); break; } } public void pop(StepSingle ss) { switch (ss.getStepType()) { case StepEnum.METHOD: case StepEnum.METHOD2: add((MethodStep) ss); break; case StepEnum.SQL: case StepEnum.SQL2: case StepEnum.SQL3: add((SqlStep) ss); break; case StepEnum.APICALL: add((ApiCallStep) ss); break; } } protected void add(SocketStep m) { if (sockets == null) sockets = new LongKeyMap<Step>(); long skid = m.getSocketId(); SocketSum sksum = (SocketSum) sockets.get(skid); if (sksum != null) { sksum.add(m.elapsed, sksum.error != 0); return; } if (totalCount >= BUFFER_SIZE) { process(); } sksum = new SocketSum(); sksum.ipaddr = m.ipaddr; sksum.port = m.port; sksum.add(m.elapsed, sksum.error != 0); sockets.put(skid, sksum); totalCount++; } protected void add(MethodStep m) { if (methods == null) methods = new IntKeyMap<Step>(); MethodSum msum = (MethodSum) methods.get(m.hash); if (msum != null) { msum.hash = m.hash; msum.add(m.elapsed, m.cputime); return; } if (totalCount >= BUFFER_SIZE) { process(); } msum = new MethodSum(); msum.hash = m.hash; msum.add(m.elapsed, m.cputime); methods.put(m.hash, msum); totalCount++; } protected void add(SqlStep ss) { if (sqls == null) sqls = new IntKeyMap<Step>(); SqlSum ssum = (SqlSum) sqls.get(ss.hash); if (ssum != null) { ssum.hash = ss.hash; if (ss.error == 0) { ssum.add(ss.elapsed, ss.cputime, ss.param); } else { ssum.addError(ss.elapsed, ss.cputime, ss.param); } return; } if (totalCount >= BUFFER_SIZE) { process(); } ssum = new SqlSum(); ssum.hash = ss.hash; if (ss.error == 0) { ssum.add(ss.elapsed, ss.cputime, ss.param); } else { ssum.addError(ss.elapsed, ss.cputime, ss.param); } sqls.put(ss.hash, ssum); totalCount++; } protected void add(ApiCallStep sc) { if (apicalls == null) apicalls = new IntKeyMap<Step>(); ApiCallSum scs = (ApiCallSum) apicalls.get(sc.hash); if (scs != null) { scs.hash = sc.hash; scs.count++; scs.elapsed += sc.elapsed; scs.cputime += sc.cputime; if (sc.error != 0) { scs.error++; } return; } if (totalCount >= BUFFER_SIZE) { process(); } scs = new ApiCallSum(); scs.hash = sc.hash; scs.count = 1; scs.elapsed = sc.elapsed; scs.cputime = sc.cputime; if (sc.error != 0) { scs.error = 1; } apicalls.put(sc.hash, scs); totalCount++; } public void close(boolean ok) { if (ok && totalCount > 0) { process(); } } }