2424import com .microsoft .applicationinsights .agent .internal .exporter .models .MonitorDomain ;
2525import com .microsoft .applicationinsights .agent .internal .exporter .models .RemoteDependencyData ;
2626import com .microsoft .applicationinsights .agent .internal .exporter .models .RequestData ;
27+ import com .microsoft .applicationinsights .agent .internal .exporter .models .StackFrame ;
2728import com .microsoft .applicationinsights .agent .internal .exporter .models .TelemetryExceptionData ;
29+ import com .microsoft .applicationinsights .agent .internal .exporter .models .TelemetryExceptionDetails ;
2830import com .microsoft .applicationinsights .agent .internal .exporter .models .TelemetryItem ;
2931import com .microsoft .applicationinsights .agent .internal .perfcounter .CpuPerformanceCounterCalculator ;
32+ import com .microsoft .applicationinsights .agent .internal .quickpulse .model .QuickPulseDependencyDocument ;
33+ import com .microsoft .applicationinsights .agent .internal .quickpulse .model .QuickPulseDocument ;
34+ import com .microsoft .applicationinsights .agent .internal .quickpulse .model .QuickPulseExceptionDocument ;
35+ import com .microsoft .applicationinsights .agent .internal .quickpulse .model .QuickPulseRequestDocument ;
3036import com .microsoft .applicationinsights .agent .internal .telemetry .TelemetryClient ;
3137import java .lang .management .ManagementFactory ;
3238import java .lang .management .MemoryMXBean ;
39+ import java .util .ArrayList ;
40+ import java .util .HashMap ;
41+ import java .util .List ;
42+ import java .util .Map ;
3343import java .util .concurrent .atomic .AtomicInteger ;
3444import java .util .concurrent .atomic .AtomicLong ;
3545import java .util .concurrent .atomic .AtomicReference ;
@@ -50,6 +60,7 @@ static class FinalCounters {
5060 public final int unsuccessfulRdds ;
5161 public final long memoryCommitted ;
5262 public final double cpuUsage ;
63+ public final List <QuickPulseDocument > documentList = new ArrayList <>();
5364
5465 public FinalCounters (
5566 Counters currentCounters ,
@@ -82,6 +93,9 @@ public FinalCounters(
8293 this .rdds = countAndDuration .count ;
8394 this .rddsDuration = countAndDuration .duration ;
8495 this .unsuccessfulRdds = currentCounters .unsuccessfulRdds .get ();
96+ synchronized (currentCounters .documentList ) {
97+ this .documentList .addAll (currentCounters .documentList );
98+ }
8599 }
86100 }
87101
@@ -106,6 +120,7 @@ static class Counters {
106120
107121 final AtomicLong rddsAndDuations = new AtomicLong (0 );
108122 final AtomicInteger unsuccessfulRdds = new AtomicInteger (0 );
123+ final List <QuickPulseDocument > documentList = new ArrayList <>();
109124
110125 static long encodeCountAndDuration (long count , long duration ) {
111126 if (count > MAX_COUNT || duration > MAX_DURATION ) {
@@ -166,7 +181,7 @@ public synchronized FinalCounters getAndRestart() {
166181 return null ;
167182 }
168183
169- /*@VisibleForTesting*/
184+ // only used by tests
170185 synchronized FinalCounters peek () {
171186 Counters currentCounters = this .counters .get (); // this should be the only differece
172187 if (currentCounters != null ) {
@@ -199,7 +214,7 @@ public void add(TelemetryItem telemetryItem) {
199214 } else if (data instanceof RemoteDependencyData ) {
200215 addDependency ((RemoteDependencyData ) data , itemCount );
201216 } else if (data instanceof TelemetryExceptionData ) {
202- addException (itemCount );
217+ addException (( TelemetryExceptionData ) data , itemCount );
203218 }
204219 }
205220
@@ -218,15 +233,59 @@ private void addDependency(RemoteDependencyData telemetry, int itemCount) {
218233 if (success != null && !success ) { // success should not be null
219234 counters .unsuccessfulRdds .incrementAndGet ();
220235 }
236+ QuickPulseDependencyDocument quickPulseDependencyDocument = new QuickPulseDependencyDocument ();
237+ quickPulseDependencyDocument .setDocumentType ("RemoteDependency" );
238+ quickPulseDependencyDocument .setType ("DependencyTelemetryDocument" );
239+ quickPulseDependencyDocument .setOperationId (telemetry .getId ());
240+ quickPulseDependencyDocument .setVersion ("1.0" );
241+ quickPulseDependencyDocument .setName (telemetry .getName ());
242+ quickPulseDependencyDocument .setCommandName (telemetry .getData ());
243+ quickPulseDependencyDocument .setTarget (telemetry .getTarget ());
244+ quickPulseDependencyDocument .setSuccess (telemetry .isSuccess ());
245+ quickPulseDependencyDocument .setDuration (telemetry .getDuration ());
246+ quickPulseDependencyDocument .setResultCode (telemetry .getResultCode ());
247+ quickPulseDependencyDocument .setOperationName (telemetry .getId ());
248+ quickPulseDependencyDocument .setDependencyTypeName (telemetry .getType ());
249+ quickPulseDependencyDocument .setProperties (
250+ aggregateProperties (telemetry .getProperties (), telemetry .getMeasurements ()));
251+ synchronized (counters .documentList ) {
252+ counters .documentList .add (quickPulseDependencyDocument );
253+ }
221254 }
222255
223- private void addException (int itemCount ) {
256+ private void addException (TelemetryExceptionData exceptionData , int itemCount ) {
224257 Counters counters = this .counters .get ();
225258 if (counters == null ) {
226259 return ;
227260 }
228261
229262 counters .exceptions .addAndGet (itemCount );
263+ QuickPulseExceptionDocument quickPulseExceptionDocument = new QuickPulseExceptionDocument ();
264+ quickPulseExceptionDocument .setDocumentType ("Exception" );
265+ quickPulseExceptionDocument .setType ("ExceptionTelemetryDocument" );
266+ quickPulseExceptionDocument .setOperationId (exceptionData .getProblemId ());
267+ quickPulseExceptionDocument .setVersion ("1.0" );
268+ List <TelemetryExceptionDetails > exceptionList = exceptionData .getExceptions ();
269+ StringBuilder exceptions = new StringBuilder ();
270+ if (exceptionList != null && exceptionList .size () > 0 ) {
271+ List <StackFrame > parsedStack = exceptionList .get (0 ).getParsedStack ();
272+ String stack = exceptionList .get (0 ).getStack ();
273+ if (parsedStack != null && parsedStack .size () > 0 ) {
274+ for (StackFrame stackFrame : parsedStack ) {
275+ if (stackFrame != null && stackFrame .getAssembly () != null ) {
276+ exceptions .append (stackFrame .getAssembly ()).append ("\n " );
277+ }
278+ }
279+ } else if (stack != null && stack .length () > 0 ) {
280+ exceptions .append (stack );
281+ }
282+ quickPulseExceptionDocument .setException (exceptions .toString ());
283+ quickPulseExceptionDocument .setExceptionMessage (exceptionList .get (0 ).getMessage ());
284+ quickPulseExceptionDocument .setExceptionType (exceptionList .get (0 ).getTypeName ());
285+ }
286+ synchronized (counters .documentList ) {
287+ counters .documentList .add (quickPulseExceptionDocument );
288+ }
230289 }
231290
232291 private void addRequest (RequestData requestTelemetry , int itemCount ) {
@@ -241,6 +300,32 @@ private void addRequest(RequestData requestTelemetry, int itemCount) {
241300 if (!requestTelemetry .isSuccess ()) {
242301 counters .unsuccessfulRequests .incrementAndGet ();
243302 }
303+ QuickPulseRequestDocument quickPulseRequestDocument = new QuickPulseRequestDocument ();
304+ quickPulseRequestDocument .setDocumentType ("Request" );
305+ quickPulseRequestDocument .setType ("RequestTelemetryDocument" );
306+ quickPulseRequestDocument .setOperationId (requestTelemetry .getId ());
307+ quickPulseRequestDocument .setVersion ("1.0" );
308+ quickPulseRequestDocument .setSuccess (requestTelemetry .isSuccess ());
309+ quickPulseRequestDocument .setDuration (requestTelemetry .getDuration ());
310+ quickPulseRequestDocument .setResponseCode (requestTelemetry .getResponseCode ());
311+ quickPulseRequestDocument .setOperationName (requestTelemetry .getName ());
312+ quickPulseRequestDocument .setProperties (
313+ aggregateProperties (requestTelemetry .getProperties (), requestTelemetry .getMeasurements ()));
314+ synchronized (counters .documentList ) {
315+ counters .documentList .add (quickPulseRequestDocument );
316+ }
317+ }
318+
319+ private static Map <String , String > aggregateProperties (
320+ Map <String , String > properties , Map <String , Double > measurements ) {
321+ Map <String , String > aggregatedProperties = new HashMap <>();
322+ if (measurements != null ) {
323+ measurements .forEach ((k , v ) -> aggregatedProperties .put (k , String .valueOf (v )));
324+ }
325+ if (properties != null ) {
326+ aggregatedProperties .putAll (properties );
327+ }
328+ return aggregatedProperties ;
244329 }
245330
246331 // TODO (trask) optimization: move live metrics request capture to OpenTelemetry layer so don't
0 commit comments