Trace Tool: Download Trace Session button is not working anymore with latest Edge Private 4.52.00

Hi all

In the Edge UI Trace tool, the “Download Trace Session” button is not working anymore after latest Edge Private 4.52.00 version installed. That means there’s no action invoked for button click.

Is anybody aware of this issue?

Regards

Solved Solved
1 2 260
1 ACCEPTED SOLUTION

We are aware of this issue and currently triaging it. Internal reference to this is b/273743923. If you have not already, please open a support ticket so we can communicate updates through the Apigee Support channel.

View solution in original post

2 REPLIES 2

We are aware of this issue and currently triaging it. Internal reference to this is b/273743923. If you have not already, please open a support ticket so we can communicate updates through the Apigee Support channel.

Thanks a lot. I created the support case for this issue.

I've also have simple workaround for offline trace while the button is not working.

  1. Before you want trace the API call or click the “Start Trace Session” button, open the Developer tools (right click + Inspect   OR F12)
  2. Start Trace Session and make API call
  3. Copy the JSON trace data from the DevTools window (in the Network tab click one of the calls with name ‘data’)
  4. Paste the JSON trace data to file in your local file system
  5. Adjust the paths in the Java class
  6. Run the Java class (it generates the trace xml file that can be used as offline trace)

Simple Java class (you need org.json.simple-0.4.jar, json-20230227.jar)

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Iterator;


public class ConvertToTraceFileV4 {

    public static void main(String[] args) {

        String debugIdCopied = "fa4c2fab-5c11-4611-9664-24daa2446ead___T-T027-GRTD___dc-1___3"; //replace with the one in the DevTools or leave it as-is
        String localJsonfileInPath = "P:\\Documents\\MKH\\DOWNLOADS\\trace-test.json";
        String localXmlfileOutPath = "P:\\Documents\\MKH\\DOWNLOADS\\trace";
        StringBuilder traceFileName = new StringBuilder();
        StringBuilder epoch = new StringBuilder();

        JSONParser parser = new JSONParser();

        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.newDocument();
            //doc.setXmlStandalone(true);

            Element rootElement = doc.createElement("DebugSession");
            doc.appendChild(rootElement);

            Element retrieved = doc.createElement("Retrieved");

            String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
            String date = simpleDateFormat.format(new Date());
            retrieved.setTextContent(date);
            rootElement.appendChild(retrieved);

            Element organization = doc.createElement("Organization");
            organization.setTextContent("test-map-api");
            rootElement.appendChild(organization);

            Element environment = doc.createElement("Environment");
            environment.setTextContent("test-map-f");
            rootElement.appendChild(environment);

            Element api = doc.createElement("API");
            api.setTextContent("TestProxy");
            rootElement.appendChild(api);

            Element revision = doc.createElement("Revision");
            revision.setTextContent("1");
            rootElement.appendChild(revision);

            Element sessionId = doc.createElement("SessionId");
            sessionId.setTextContent("1679096747258");
            rootElement.appendChild(sessionId);

            Element messages = doc.createElement("Messages");

            Element message = doc.createElement("Message");
            messages.appendChild(message);

            Element debugId = doc.createElement("DebugId");
            debugId.setTextContent(debugIdCopied);
            Element data = doc.createElement("Data");
            message.appendChild(debugId);


            Object obj = parser.parse(new FileReader(localJsonfileInPath));
            JSONObject jsonObject = (JSONObject) obj;

            Element completed = doc.createElement("Completed");
            completed.setTextContent(String.valueOf(jsonObject.get("completed")));
            data.appendChild(completed);

            JSONArray points = (JSONArray) jsonObject.get("point");//main
            Iterator<JSONObject> pointsiterator = points.iterator();
            while (pointsiterator.hasNext()) {

                JSONObject pointObj = (JSONObject) pointsiterator.next();

                //create Point objects e.g. Paused, Resumed, StateChange, FlowInfo, Condition, Execution, DebugMask
                Element point = doc.createElement("Point");
                point.setAttribute("id", pointObj.get("id").toString());

                //Point objects containing other objects as multiple ActionResult .e.g DebugInfo, RequestMessage, ResponseMessage, VariableAccess
                JSONArray results = (JSONArray) pointObj.get("results");
                if (results != null && !results.isEmpty()) {
                    Iterator<JSONObject> resultIterator = results.iterator();
                    while (resultIterator.hasNext()) {

                        JSONObject resultObj = (JSONObject) resultIterator.next();

                        if (resultObj.get("ActionResult").toString().equals("DebugInfo")) { //DebugInfo object
                            Element debugInfo = doc.createElement("DebugInfo");

                            Element timestamp = doc.createElement("Timestamp");
                            timestamp.setTextContent(resultObj.get("timestamp").toString());

                            if (epoch.length() <= 0) {
                                epoch.append(resultObj.get("timestamp").toString());
                            }
                            debugInfo.appendChild(timestamp);

                            Element debugInfoProps = doc.createElement("Properties");

                            JSONObject properties = (JSONObject) resultObj.get("properties");
                            JSONArray namevaluePairs = (JSONArray) properties.get("property");
                            Iterator<JSONObject> namevalueiterator = namevaluePairs.iterator();
                            while (namevalueiterator.hasNext()) {

                                JSONObject nvObj = (JSONObject) namevalueiterator.next();
                                if (nvObj.get("name").toString().equals("environment.orgname")) {
                                    organization.setTextContent(nvObj.get("value").toString());
                                    traceFileName.append("_" + nvObj.get("value").toString());
                                }
                                if (nvObj.get("name").toString().equals("environment.name")) {
                                    environment.setTextContent(nvObj.get("value").toString());
                                    traceFileName.append("_" + nvObj.get("value").toString());
                                }
                                if (nvObj.get("name").toString().equals("apiproxy.name")) {
                                    api.setTextContent(nvObj.get("value").toString());
                                    traceFileName.append("_" + nvObj.get("value").toString());
                                }
                                if (nvObj.get("name").toString().equals("apiproxy.revision")) {
                                    revision.setTextContent(nvObj.get("value").toString());
                                    traceFileName.append("_" + nvObj.get("value").toString());
                                }
                                Element property = doc.createElement("Property");
                                property.setAttribute("name", nvObj.get("name").toString());
                                property.setTextContent(nvObj.get("value").toString());
                                debugInfoProps.appendChild(property);
                            }
                            debugInfo.appendChild(debugInfoProps);
                            point.appendChild(debugInfo);
                        }

                        if (resultObj.get("ActionResult").toString().equals("RequestMessage")) {
                            Element requestMessage = doc.createElement(resultObj.get("ActionResult").toString());

                            if (resultObj.get("verb").toString().equals("POST") && resultObj.get("content") != null) {
                                Element reqcontent = doc.createElement("Content");
                                reqcontent.setTextContent(resultObj.get("content").toString());
                                requestMessage.appendChild(reqcontent);
                            }

                            JSONArray headers = (JSONArray) resultObj.get("headers");
                            Element requestHeaders = doc.createElement("Headers");
                            Iterator<JSONObject> headersiterator = headers.iterator();
                            while (headersiterator.hasNext()) {

                                JSONObject nvObj = (JSONObject) headersiterator.next();

                                Element header = doc.createElement("Header");
                                header.setAttribute("name", nvObj.get("name").toString());
                                header.setTextContent(nvObj.get("value").toString());
                                requestHeaders.appendChild(header);
                            }

                            requestMessage.appendChild(requestHeaders);

                            Element uri = doc.createElement("URI");
                            uri.setTextContent(resultObj.get("uRI").toString());
                            requestMessage.appendChild(uri);

                            Element verb = doc.createElement("Verb");
                            verb.setTextContent(resultObj.get("verb").toString());
                            requestMessage.appendChild(verb);

                            point.appendChild(requestMessage);
                        }

                        if (resultObj.get("ActionResult").toString().equals("VariableAccess")) {
                            Element variableAccess = doc.createElement(resultObj.get("ActionResult").toString());

                            JSONArray varList = (JSONArray) resultObj.get("accessList");
                            if (!varList.isEmpty()) {
                                Iterator<JSONObject> varListiterator = varList.iterator();
                                while (varListiterator.hasNext()) {
                                    JSONObject varListOjb = (JSONObject) varListiterator.next();
                                    if (varListOjb.get("Get") != null) {
                                        JSONObject getObj = (JSONObject) varListOjb.get("Get");
                                        Element get = doc.createElement("Get");
                                        get.setAttribute("name", getObj.get("name").toString());
                                        if (getObj.get("value") != null) {
                                            get.setAttribute("value", getObj.get("value").toString());
                                        }

                                        variableAccess.appendChild(get);

                                    } else if (varListOjb.get("Set") != null) {
                                        JSONObject setObj = (JSONObject) varListOjb.get("Set");
                                        Element set = doc.createElement("Set");
                                        set.setAttribute("success", setObj.get("success").toString());
                                        if (setObj.get("value") != null) {
                                            set.setAttribute("value", setObj.get("value").toString());
                                        }
                                        set.setAttribute("name", setObj.get("name").toString());

                                        variableAccess.appendChild(set);
                                    }
                                }

                            }
                            point.appendChild(variableAccess);
                        }

                        if (resultObj.get("ActionResult").toString().equals("ResponseMessage")) {
                            Element responseMessage = doc.createElement(resultObj.get("ActionResult").toString());

                            if (resultObj.get("content") != null) {
                                Element content = doc.createElement("Content");
                                content.setTextContent(resultObj.get("content").toString());
                                responseMessage.appendChild(content);
                            }

                            JSONArray responseHeaders = (JSONArray) resultObj.get("headers");
                            Element headers = doc.createElement("Headers");
                            Iterator<JSONObject> responseheadersiterator = responseHeaders.iterator();
                            while (responseheadersiterator.hasNext()) {

                                JSONObject nvObj = (JSONObject) responseheadersiterator.next();

                                Element header = doc.createElement("Header");
                                header.setAttribute("name", nvObj.get("name").toString());
                                header.setTextContent(nvObj.get("value").toString());
                                headers.appendChild(header);
                            }
                            responseMessage.appendChild(headers);

                            if (resultObj.get("reasonPhrase") != null) {
                                Element reasonPhrase = doc.createElement("ReasonPhrase");
                                reasonPhrase.setTextContent(resultObj.get("reasonPhrase").toString());
                                responseMessage.appendChild(reasonPhrase);
                            }

                            if (resultObj.get("statusCode") != null) {
                                Element statusCode = doc.createElement("StatusCode");
                                statusCode.setTextContent(resultObj.get("statusCode").toString());
                                responseMessage.appendChild(statusCode);
                            }

                            point.appendChild(responseMessage);
                        }

                        if (resultObj.get("ActionResult").toString().equals("ErrorMessage")) {
                            Element errorMessage = doc.createElement(resultObj.get("ActionResult").toString());

                            if (resultObj.get("content") != null) {
                                Element content = doc.createElement("Content");
                                content.setTextContent(resultObj.get("content").toString());
                                errorMessage.appendChild(content);
                            }

                            JSONArray responseHeaders = (JSONArray) resultObj.get("headers");
                            Element headers = doc.createElement("Headers");
                            Iterator<JSONObject> responseheadersiterator = responseHeaders.iterator();
                            while (responseheadersiterator.hasNext()) {

                                JSONObject nvObj = (JSONObject) responseheadersiterator.next();

                                Element header = doc.createElement("Header");
                                header.setAttribute("name", nvObj.get("name").toString());
                                header.setTextContent(nvObj.get("value").toString());
                                headers.appendChild(header);
                            }
                            errorMessage.appendChild(headers);

                            if (resultObj.get("reasonPhrase") != null) {
                                Element reasonPhrase = doc.createElement("ReasonPhrase");
                                reasonPhrase.setTextContent(resultObj.get("reasonPhrase").toString());
                                errorMessage.appendChild(reasonPhrase);
                            }

                            if (resultObj.get("statusCode") != null) {
                                Element statusCode = doc.createElement("StatusCode");
                                statusCode.setTextContent(resultObj.get("statusCode").toString());
                                errorMessage.appendChild(statusCode);
                            }

                            point.appendChild(errorMessage);
                        }

                        data.appendChild(point);
                    }
                } else {
                    data.appendChild(point);
                }
                message.appendChild(data);
                messages.appendChild(message);
                rootElement.appendChild(messages);
            }

            ZonedDateTime zonedDateTime = LocalDateTime.parse(epoch.toString(), DateTimeFormatter.ofPattern("dd-MM-yy HH:mm:ss:SSS")).atZone(ZoneId.of("UTC"));
            long epochMilli = zonedDateTime.toInstant().toEpochMilli();

            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new File(localXmlfileOutPath + traceFileName.toString() + "_"+epochMilli +".xml"));

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            //transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
            transformer.setOutputProperty(OutputKeys.VERSION, "1.0");
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            transformer.transform(source, result);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }
}