Grafana dashboard: Pixie HTTP Traces
Description: Dashboard includes a table of the most recent full-body HTTP messages in your cluster. 

For more info about request tracing using Pixie, see the [tutorial](https://docs.px.dev/tutorials/pixie-101/request-tracing).

{
  "__inputs": [
    {
      "name": "DS_PIXIE_GRAFANA DATASOURCE PLUGIN",
      "label": "Pixie Grafana Datasource Plugin",
      "description": "",
      "type": "datasource",
      "pluginId": "pixie-pixie-datasource",
      "pluginName": "Pixie Grafana Datasource Plugin"
    }
  ],
  "__requires": [
    {
      "type": "datasource",
      "id": "pixie-pixie-datasource",
      "name": "Pixie Grafana Datasource Plugin",
      "version": "0.0.9"
    },
    {
      "type": "panel",
      "id": "table",
      "name": "Table",
      "version": ""
    }
  ],
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "target": {
          "limit": 100,
          "matchAny": false,
          "tags": [],
          "type": "dashboard"
        },
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "graphTooltip": 0,
  "links": [],
  "panels": [
    {
      "datasource": "${DS_PIXIE_GRAFANA DATASOURCE PLUGIN}",
      "fieldConfig": {
        "defaults": {
          "color": {
            "mode": "thresholds"
          },
          "custom": {
            "align": "auto",
            "displayMode": "auto",
            "inspect": false
          },
          "mappings": [],
          "thresholds": {
            "mode": "absolute",
            "steps": [
              {
                "color": "green",
                "value": null
              },
              {
                "color": "red",
                "value": 80
              }
            ]
          }
        },
        "overrides": [
          {
            "matcher": {
              "id": "byName",
              "options": "latency"
            },
            "properties": [
              {
                "id": "unit",
                "value": "ms"
              },
              {
                "id": "custom.displayMode",
                "value": "color-text"
              },
              {
                "id": "thresholds",
                "value": {
                  "mode": "absolute",
                  "steps": [
                    {
                      "color": "green",
                      "value": null
                    },
                    {
                      "color": "light-orange",
                      "value": 150
                    },
                    {
                      "color": "red",
                      "value": 300
                    }
                  ]
                }
              },
              {
                "id": "decimals",
                "value": 1
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "req_body_size"
            },
            "properties": [
              {
                "id": "unit",
                "value": "decbytes"
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "resp_status"
            },
            "properties": [
              {
                "id": "custom.displayMode",
                "value": "color-text"
              },
              {
                "id": "thresholds",
                "value": {
                  "mode": "absolute",
                  "steps": [
                    {
                      "color": "green",
                      "value": null
                    },
                    {
                      "color": "red",
                      "value": 400
                    }
                  ]
                }
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "resp_body_size"
            },
            "properties": [
              {
                "id": "unit",
                "value": "deckbytes"
              },
              {
                "id": "decimals",
                "value": 1
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "source"
            },
            "properties": [
              {
                "id": "links",
                "value": [
                  {
                    "title": "",
                    "url": "/d/_t3foxCnz/px-pod?orgId=1&${pixieCluster:queryparam}&var-pixiePod=${__data.fields.source}"
                  }
                ]
              }
            ]
          },
          {
            "matcher": {
              "id": "byName",
              "options": "destination"
            },
            "properties": [
              {
                "id": "links",
                "value": [
                  {
                    "title": "",
                    "url": "/d/_t3foxCnz/px-pod?orgId=1&${pixieCluster:queryparam}&var-pixiePod=${__data.fields.destination}"
                  }
                ]
              }
            ]
          }
        ]
      },
      "gridPos": {
        "h": 22,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "id": 2,
      "options": {
        "footer": {
          "fields": "",
          "reducer": [
            "sum"
          ],
          "show": false
        },
        "showHeader": true,
        "sortBy": [
          {
            "desc": true,
            "displayName": "latency"
          }
        ]
      },
      "pluginVersion": "7.5.1",
      "targets": [
        {
          "queryBody": {
            "pxlScript": "# Copyright 2018- The Pixie Authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n# SPDX-License-Identifier: Apache-2.0\n\n''' HTTP Data Tracer\n\nThis script traces all HTTP/HTTP2 data on the cluster.\n'''\nimport px\n\n# $pixieCluster - work around for grafana to update panel on variable change\n\ndef http_data(start_time: int, source_filter: str, destination_filter: str, num_head: int):\n\n    df = px.DataFrame(table='http_events', start_time=start_time)\n\n    # Add context.\n    df.node = df.ctx['node']\n    df.pid = px.upid_to_pid(df.upid)\n    df = add_source_dest_columns(df)\n\n    # Filter out entities as specified by the user.\n    df = df[px.contains(df.source, source_filter)]\n    df = df[px.contains(df.destination, destination_filter)]\n\n    # Add additional filters below:\n\n    # Restrict number of results.\n    df = df.head(num_head)\n    # Avoid conversion to wide format\n    df.timestamp = df.time_\n    df = df.drop(columns=['time_'])\n    \n    df.latency = df.latency / px.pow(10,6)\n    df.resp_body_size = df.resp_body_size / px.pow(2,10) \n\n    # Order columns.\n    df = df['timestamp', 'source', 'destination', 'latency', 'major_version', 'req_path',\n            'req_method', 'req_headers', 'req_body', 'req_body_size', 'resp_status',\n            'resp_message', 'resp_headers', 'resp_body', 'resp_body_size']\n\n    return df\n\n\ndef add_source_dest_columns(df):\n    ''' Add source and destination columns for the HTTP request.\n\n    HTTP requests are traced server-side (trace_role==2), unless the server is\n    outside of the cluster in which case the request is traced client-side (trace_role==1).\n\n    When trace_role==2, the HTTP request source is the remote_addr column\n    and destination is the pod column. When trace_role==1, the HTTP request\n    source is the pod column and the destination is the remote_addr column.\n\n    Input DataFrame must contain trace_role, upid, remote_addr columns.\n    '''\n    df.pod = df.ctx['pod']\n    df.namespace = df.ctx['namespace']\n\n    # If remote_addr is a pod, get its name. If not, use IP address.\n    df.ra_pod = px.pod_id_to_pod_name(px.ip_to_pod_id(df.remote_addr))\n    df.is_ra_pod = df.ra_pod != ''\n    df.ra_name = px.select(df.is_ra_pod, df.ra_pod, df.remote_addr)\n\n    df.is_server_tracing = df.trace_role == 2\n    df.is_source_pod_type = px.select(df.is_server_tracing, df.is_ra_pod, True)\n    df.is_dest_pod_type = px.select(df.is_server_tracing, True, df.is_ra_pod)\n\n    # Set source and destination based on trace_role.\n    df.source = px.select(df.is_server_tracing, df.ra_name, df.pod)\n    df.destination = px.select(df.is_server_tracing, df.pod, df.ra_name)\n\n    # Filter out messages with empty source / destination.\n    df = df[df.source != '']\n    df = df[df.destination != '']\n\n    df = df.drop(['ra_pod', 'is_ra_pod', 'ra_name', 'is_server_tracing'])\n    return df\n\noutput = http_data($__from, '$sourceFilter', '$destinationFilter', $maxNumRecords)\n\npx.display(output)"
          },
          "queryType": "run-script",
          "refId": "A"
        }
      ],
      "title": "Table",
      "type": "table"
    }
  ],
  "refresh": 2,
  "schemaVersion": 27,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": [
      {
        "current": {},
        "datasource": "${DS_PIXIE_GRAFANA DATASOURCE PLUGIN}",
        "definition": "Clusters",
        "hide": 0,
        "includeAll": false,
        "multi": false,
        "name": "pixieCluster",
        "options": [],
        "query": {
          "queryType": "get-clusters"
        },
        "refresh": 2,
        "regex": "",
        "skipUrlSync": false,
        "sort": 0,
        "type": "query"
      },
      {
        "current": {
          "selected": false,
          "text": "",
          "value": ""
        },
        "description": "The partial string to match the 'source' column",
        "hide": 0,
        "name": "sourceFilter",
        "options": [
          {
            "selected": true,
            "text": "",
            "value": ""
          }
        ],
        "query": "",
        "skipUrlSync": false,
        "type": "textbox"
      },
      {
        "current": {
          "selected": false,
          "text": "",
          "value": ""
        },
        "description": "The partial string to match the 'destination' column",
        "hide": 0,
        "name": "destinationFilter",
        "options": [
          {
            "selected": true,
            "text": "",
            "value": ""
          }
        ],
        "query": "",
        "skipUrlSync": false,
        "type": "textbox"
      },
      {
        "current": {
          "selected": false,
          "text": "1000",
          "value": "1000"
        },
        "hide": 0,
        "name": "maxNumRecords",
        "options": [
          {
            "selected": true,
            "text": "1000",
            "value": "1000"
          }
        ],
        "query": "1000",
        "skipUrlSync": false,
        "type": "textbox"
      }
    ]
  },
  "time": {
    "from": "now-15m",
    "to": "now"
  },
  "timepicker": {},
  "timezone": "",
  "title": "Pixie HTTP Traces",
  "description": "Dashboard includes a table of the most recent full-body HTTP messages in your cluster. ",
  "version": 2,
  "weekStart": "",
  "gnetId": 16999
}