77package com .nr .agent .instrumentation .utils .span ;
88
99import com .newrelic .api .agent .NewRelic ;
10+ import com .newrelic .bootstrap .EmbeddedJarFilesImpl ;
1011import io .opentelemetry .api .trace .SpanKind ;
1112import org .json .simple .JSONArray ;
1213import org .json .simple .JSONObject ;
1314import org .json .simple .parser .JSONParser ;
15+ import org .json .simple .parser .ParseException ;
1416
17+ import java .io .IOException ;
1518import java .io .InputStream ;
1619import java .io .InputStreamReader ;
20+ import java .nio .charset .StandardCharsets ;
1721import java .util .ArrayList ;
1822import java .util .HashMap ;
1923import java .util .List ;
2024import java .util .Map ;
2125import java .util .Set ;
26+ import java .util .jar .JarEntry ;
27+ import java .util .jar .JarFile ;
2228import java .util .logging .Level ;
2329
2430public class AttributeMapper {
2531 private static final String MAPPING_RESOURCE = "attribute-mappings.json" ;
32+ private static final String INSTRUMENTATION_JAR_LOCATION = "instrumentation/opentelemetry-sdk-extension-autoconfigure-1.28.0-1.0" ;
2633
2734 private static volatile AttributeMapper instance ;
2835 private final Map <SpanKind , Map <AttributeType , List <AttributeKey >>> mappings = new HashMap <>();
@@ -42,35 +49,34 @@ public static AttributeMapper getInstance() {
4249 if (instance == null ) {
4350 synchronized (AttributeMapper .class ) {
4451 if (instance == null ) {
45- try (InputStream inputStream = AttributeMapper .class .getClassLoader ().getResourceAsStream (MAPPING_RESOURCE );
46- InputStreamReader reader = new InputStreamReader (inputStream )) {
47-
48- instance = new AttributeMapper ();
49-
50- JSONParser parser = new JSONParser ();
51- JSONArray rootArray = (JSONArray ) parser .parse (reader );
52-
53- for (Object spanKindObj : rootArray ) {
54- // Span kind and a list of attribute types
55- JSONObject spanKindObject = (JSONObject ) spanKindObj ;
56- SpanKind spanKind = SpanKind .valueOf ((String ) spanKindObject .get ("spanKind" ));
57- JSONArray jsonAttributeTypes = (JSONArray ) spanKindObject .get ("attributeTypes" );
58-
59- for (Object typeObj : jsonAttributeTypes ) {
60- JSONObject categoryObject = (JSONObject ) typeObj ;
61-
62- // Grab the attribute type (Port, Host, etc) and then iterate over the actual attribute keys
63- AttributeType attributeType = AttributeType .valueOf ((String ) categoryObject .get ("attributeType" ));
64- JSONArray jsonAttributes = (JSONArray ) categoryObject .get ("attributes" );
65- for (Object jsonAttribute : jsonAttributes ) {
66- JSONObject attribute = (JSONObject ) jsonAttribute ;
67- instance .addAttributeMapping (spanKind , attributeType , new AttributeKey ((String ) attribute .get ("name" ), (String ) attribute .get ("version" )));
52+ try {
53+ JSONArray rootArray = parseJsonResourceFromAgentJar (INSTRUMENTATION_JAR_LOCATION , MAPPING_RESOURCE );
54+
55+ if (rootArray != null ) {
56+ instance = new AttributeMapper ();
57+
58+ for (Object spanKindObj : rootArray ) {
59+ // Span kind and a list of attribute types
60+ JSONObject spanKindObject = (JSONObject ) spanKindObj ;
61+ SpanKind spanKind = SpanKind .valueOf ((String ) spanKindObject .get ("spanKind" ));
62+ JSONArray jsonAttributeTypes = (JSONArray ) spanKindObject .get ("attributeTypes" );
63+
64+ for (Object typeObj : jsonAttributeTypes ) {
65+ JSONObject categoryObject = (JSONObject ) typeObj ;
66+
67+ // Grab the attribute type (Port, Host, etc) and then iterate over the actual attribute keys
68+ AttributeType attributeType = AttributeType .valueOf ((String ) categoryObject .get ("attributeType" ));
69+ JSONArray jsonAttributes = (JSONArray ) categoryObject .get ("attributes" );
70+ for (Object jsonAttribute : jsonAttributes ) {
71+ JSONObject attribute = (JSONObject ) jsonAttribute ;
72+ instance .addAttributeMapping (spanKind , attributeType , new AttributeKey ((String ) attribute .get ("name" ), (String ) attribute .get ("version" )));
73+ }
6874 }
6975 }
7076 }
7177 } catch (Exception e ) {
72- // Should never happen...
73- NewRelic .getAgent ().getLogger ().log (Level .SEVERE , "Unable to read OTel attribute mappings" , e );
78+ // Should never happen...Maybe
79+ NewRelic .getAgent ().getLogger ().log (Level .SEVERE , "OTel AttributeMapper: Unable to read OTel attribute mappings: {0} " , e . getMessage () );
7480 }
7581 }
7682 }
@@ -120,4 +126,32 @@ Map<SpanKind, Map<AttributeType, List<AttributeKey>>> getMappings() {
120126 private void addAttributeMapping (SpanKind spanKind , AttributeType attributeType , AttributeKey attributeKey ) {
121127 this .mappings .get (spanKind ).get (attributeType ).add (attributeKey );
122128 }
129+
130+ private static JSONArray parseJsonResourceFromAgentJar (String instrumentationJarLocation , String jsonResourceName ) {
131+ try (JarFile instrumentationJarFile = new JarFile (EmbeddedJarFilesImpl .INSTANCE .getJarFileInAgent (instrumentationJarLocation ))) {
132+ JarEntry jsonFileJarEntry = instrumentationJarFile .getJarEntry (jsonResourceName );
133+
134+ if (jsonFileJarEntry != null ) {
135+ StringBuilder jsonStringBuilder = new StringBuilder ();
136+ try (InputStream inputStream = instrumentationJarFile .getInputStream (jsonFileJarEntry )) {
137+ byte [] buffer = new byte [1024 ];
138+ int bytesRead ;
139+ while ((bytesRead = inputStream .read (buffer )) != -1 ) {
140+ jsonStringBuilder .append (new String (buffer , 0 , bytesRead , StandardCharsets .UTF_8 ));
141+ }
142+ }
143+ String jsonString = jsonStringBuilder .toString ();
144+
145+ JSONParser parser = new JSONParser ();
146+ return (JSONArray ) parser .parse (jsonString );
147+ } else {
148+ NewRelic .getAgent ().getLogger ().log (Level .SEVERE , "OTel AttributeMapper: JarEntry `{0}` not found in the {1} jar file" , jsonResourceName , instrumentationJarLocation );
149+ }
150+ } catch (IOException e ) {
151+ NewRelic .getAgent ().getLogger ().log (Level .SEVERE , "OTel AttributeMapper: IOException constructing JarFile: {0}" , e .getMessage ());
152+ } catch (ParseException e ) {
153+ NewRelic .getAgent ().getLogger ().log (Level .SEVERE , "OTel AttributeMapper: ParseException parsing attribute mapping JSON: {0}" , e .getMessage ());
154+ }
155+ return null ;
156+ }
123157}
0 commit comments