#pragma D option quiet #pragma D option bufsize=100m #pragma D option dynvarsize=4m inline string CACAO_PKG = "com/sun/cacao"; inline string CONTAINER_CLASS = "com/sun/cacao/container/impl/ContainerPrivate"; inline string CACAO_CLASS = "com/sun/cacao/impl/Cacao"; inline string JMXAGENT_CLASS = "com/sun/cacao/agent/impl/JmxAgent"; inline string LIFECYCLE_NOTIF = "sendLifecycleNotification"; inline string REG_MODS_METHOD = "registerModules"; inline string REG_ADAP_CONNCTOR = "registerAdaptorsAndConnectors"; inline string START_ADAP_CONNCTOR = "startAdaptorsAndConnectors"; inline string CONTAINER_START_METHOD = "start"; int CONTAINER_STAT_TS; int CACAO_PID; int TEMP_CACAO_PID; int CONTAINER_CLASS_LOADED; dtrace:::BEGIN { printf("script will exit at the end of container start\n"); printf("otherwise, Ctrl-C to end\n\n\n"); CONTAINER_CLASS_LOADED = 0; CACAO_PID = 0; TEMP_CACAO_PID = 0; CONTAINER_STAT_TS = 0; } hotspot*:::vm-shutdown /pid == CACAO_PID/ { printf("cacao stopped %d\n",CACAO_PID); printf("tracing stopped\n"); CACAO_PID = 0; } /*only interested by starting jvm*/ hotspot*:::class-loaded /TEMP_CACAO_PID == 0 && copyinstr(arg0,arg1) == CONTAINER_CLASS/ { CONTAINER_CLASS_LOADED = 1; TEMP_CACAO_PID = pid; printf("new potential cacao detected [%d]\n",TEMP_CACAO_PID); } /*try to optimize by dropping java classes and minise copy*/ hotspot*:::method-entry , hotspot*:::method-return /pid == CACAO_PID/ { self->package = copyinstr(arg1,13); self->handle_it = self->package == CACAO_PKG ? 1 : 0; self->classname = self->handle_it == 1 ? copyinstr(arg1,arg2) : (string)0; self->method_name = self->handle_it == 1 ? copyinstr(arg3,arg4) : (string)0; self->package = 0; } hotspot*:::method-entry , hotspot*:::method-return /CACAO_PID > 0 && pid != CACAO_PID/ { self->handle_it = 0; } /*detect container start*/ /*the first start method triggered will be container start*/ /*clause will be not fired until CACAO_PID is resolved*/ hotspot*:::method-entry / CACAO_PID == 0 && TEMP_CACAO_PID > 0 && CONTAINER_CLASS_LOADED == 1 && copyinstr(arg3,arg4) == CONTAINER_START_METHOD / { CONTAINER_START_TS = timestamp; printf("(%-10d) container start engaged (pid = %d).\n",timestamp,pid); /*we found the container, commit the traced pid*/ CACAO_PID = TEMP_CACAO_PID; } hotspot*:::method-entry /self->handle_it == 1 && CONTAINER_START_TS > 0 && self->classname == CONTAINER_CLASS && self->method_name == REG_MODS_METHOD/ { self->register_modules_ts = timestamp; /*printf("entering [%s:%s]\n",CONTAINER_CLASS,REG_MODS_METHOD);*/ } hotspot*:::method-return /self->handle_it == 1 && CONTAINER_START_TS > 0 && self->classname == CONTAINER_CLASS && self->method_name == REG_MODS_METHOD/ { /*printf("retruning [%s:%s]\n",CONTAINER_CLASS,REG_MODS_METHOD);*/ @times["register all modules"] = sum(timestamp - self->register_modules_ts); } hotspot*:::method-entry /self->handle_it == 1 && CONTAINER_START_TS > 0 && self->classname == JMXAGENT_CLASS && self->method_name == REG_ADAP_CONNCTOR/ { /*printf("entering [%s:%s]\n",JMXAGENT_CLASS,REG_ADAP_CONNCTOR);*/ self->reg_adaptors_ts = timestamp; } hotspot*:::method-return /self->handle_it == 1 && CONTAINER_START_TS > 0 && self->classname == JMXAGENT_CLASS && self->method_name == REG_ADAP_CONNCTOR/ { /*printf("returning [%s:%s]\n",JMXAGENT_CLASS,REG_ADAP_CONNCTOR);*/ @times[REG_ADAP_CONNCTOR] = sum(timestamp - self->reg_adaptors_ts); } hotspot*:::method-entry /self->handle_it == 1 && CONTAINER_START_TS > 0 && self->classname == JMXAGENT_CLASS && self->method_name == START_ADAP_CONNCTOR/ { /*printf("entering [%s:%s]\n",JMXAGENT_CLASS,START_ADAP_CONNCTOR);*/ self->start_adaptors_ts = timestamp; } hotspot*:::method-return /self->handle_it == 1 && CONTAINER_START_TS > 0 && self->classname == JMXAGENT_CLASS && self->method_name == START_ADAP_CONNCTOR/ { /*printf("returning [%s:%s]\n",JMXAGENT_CLASS,START_ADAP_CONNCTOR);*/ @times[START_ADAP_CONNCTOR] = sum(timestamp - self->start_adaptors_ts); } /*the first notification sent is LifecycleNotification.STARTED when container*/ /*just finish its start*/ hotspot*:::method-return /self->handle_it == 1 && CACAO_PID > 0 && self->classname == CACAO_CLASS && self->method_name == LIFECYCLE_NOTIF/ { printf("container start done\n"); @times["container start"] = sum(timestamp - CONTAINER_START_TS); exit(0); } dtrace:::END { normalize(@times, 1000000); printf("%30s - %15s\n","modules","time (secs/milliseconds)"); printa("%30s - %15@d\n",@times); }