/* * 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 scouter.agent.Configure; import scouter.agent.netio.data.DataProxy; import scouter.lang.step.DumpStep; import scouter.lang.step.Step; import scouter.lang.step.StepSingle; public class ProfileCollector implements IProfileCollector { private Configure conf = Configure.getInstance(); private TraceContext context; protected Step[] steps = new Step[conf.profile_step_max_count]; protected int pos = 0; private boolean doingDumpStepJob = false; public int currentLevel = 0; public int parentLevel = -1; public ProfileCollector(TraceContext context) { this.context = context; } /** * (syn: pushAndSetLevel) * set the step's level as the current level and increase one level(to deeper level). * @param stepSingle */ public void push(StepSingle stepSingle) { checkDumpStep(); stepSingle.index = currentLevel; stepSingle.parent = parentLevel; parentLevel = currentLevel; currentLevel++; } /** * (syn: addStep) * assign a given step to steps[pos++] * @param stepSingle */ protected void process(StepSingle stepSingle) { checkDumpStep(); steps[pos++] = stepSingle; if (pos >= steps.length) { Step[] o = steps; steps = new Step[conf.profile_step_max_count]; pos = 0; DataProxy.sendProfile(o, context); } } /** * (syn: setLevelAndAddStep) * add a step * @param stepSingle */ public void add(StepSingle stepSingle) { checkDumpStep(); stepSingle.index = currentLevel; stepSingle.parent = parentLevel; currentLevel++; process(stepSingle); } /** * (syn: pullAndAddStep) * add the step already leveled and decrease one level(to lower level). * @param stepSingle */ public void pop(StepSingle stepSingle) { checkDumpStep(); parentLevel = stepSingle.parent; process(stepSingle); } /** * send the Steps[] data * @param ok : send the data or not */ public void close(boolean ok) { checkDumpStep(); if (ok && pos > 0) { StepSingle[] newSteps = new StepSingle[pos]; System.arraycopy(steps, 0, newSteps, 0, pos); DataProxy.sendProfile(newSteps, context); } } private void checkDumpStep() { if(doingDumpStepJob) { return; } DumpStep dumpStep; doingDumpStepJob = true; while(true) { dumpStep = context.temporaryDumpSteps.poll(); if(dumpStep == null) { break; } add(dumpStep); } doingDumpStepJob = false; } }