/* * 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.counter.task; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import scouter.agent.Configure; import scouter.agent.Logger; import scouter.agent.counter.CounterBasket; import scouter.agent.counter.anotation.Counter; import scouter.agent.trace.AlertProxy; import scouter.agent.trace.TraceContext; import scouter.agent.trace.TraceContextManager; import scouter.agent.util.DumpUtil; import scouter.lang.AlertLevel; import scouter.util.DateUtil; import scouter.util.FileUtil; import scouter.util.Hexa32; import scouter.util.SysJMX; public class DebugService { Configure conf = Configure.getInstance(); long lastCheckStuckTime; @Counter public void checkService(CounterBasket pw) { PrintWriter stuckOut = null; try { boolean checkStuck = false; long now = System.currentTimeMillis(); if (now - lastCheckStuckTime >= conf.autodump_stuck_check_interval_ms) { checkStuck = true; lastCheckStuckTime = now; } StringBuilder stuckMsg = new StringBuilder(); Enumeration<TraceContext> en = TraceContextManager.getContextEnumeration(); while (en.hasMoreElements()) { TraceContext ctx = en.nextElement(); if (checkStuck) { checkStcukService(ctx, stuckOut, stuckMsg); } } if (stuckMsg.length() > 0) { AlertProxy.sendAlert(AlertLevel.WARN, "STUCK_SERVICE", stuckMsg.toString()); } } catch (Exception e) { Logger.println("A154", e.toString()); } finally { FileUtil.close(stuckOut); } } private void checkStcukService(TraceContext ctx, PrintWriter out, StringBuilder msg) { if (conf.autodump_stuck_thread_ms <= 0) return; long etime = System.currentTimeMillis() - ctx.startTime; if (etime > conf.autodump_stuck_thread_ms) { try { if (out == null) { out = open(); } out.print(ctx.thread.getId() + ":"); out.print(ctx.thread.getName() + ":"); out.println(ctx.thread.getState().name()); out.println("cpu " + SysJMX.getThreadCpuTime(ctx.thread)); out.println(Hexa32.toString32(ctx.txid)); out.print(ctx.serviceName + ":"); out.println(etime + " ms"); if (ctx.sqltext != null) { out.println("sql=" + ctx.sqltext ); if(ctx.sqlActiveArgs!=null){ out.println("[" + ctx.sqlActiveArgs + "]"); } } if (ctx.apicall_name != null) { out.println("apicall=" + ctx.apicall_name); } out.println(""); DumpUtil.printStack(out, ctx.thread.getId()); out.println(""); } catch (Exception e) { Logger.println("A155", e.toString()); FileUtil.close(out); return; } msg.append(ctx.serviceName + System.getProperty("line.separator")); msg.append(etime + " ms" + System.getProperty("line.separator")); msg.append(ctx.thread.getName() + ":"); msg.append(ctx.thread.getState().name() + ":"); msg.append("cpu " + SysJMX.getThreadCpuTime(ctx.thread) + System.getProperty("line.separator")); msg.append(Hexa32.toString32(ctx.txid) + System.getProperty("line.separator")); msg.append(System.getProperty("line.separator")); } } private PrintWriter open() throws IOException { File file = new File(conf.dump_dir, "longtx_" + conf.obj_name + "_" + DateUtil.timestampFileName()+".txt"); return new PrintWriter(new FileWriter(file)); } }