{"componentChunkName":"component---src-templates-docs-tsx","path":"/https/docs.px.dev/tutorials/custom-data/dynamic-go-logging/","result":{"data":{"site":{"siteMetadata":{"title":"Pixie Docs","docsLocation":"https://github.com/pixie-io/pixie-docs"}},"mdx":{"fields":{"id":"b1fa96bb-c032-5c32-bbd3-9d1dc00cb3e3","title":"Dynamic Logging In Go (Alpha)","slug":"/tutorials/custom-data/dynamic-go-logging"},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Dynamic Logging In Go (Alpha)\",\n  \"metaTitle\": \"Tutorials | Collecting Custom Data | Dynamic Structured Logging In Go\",\n  \"metaDescription\": \"Simple tutorial to show how dynamic structured logging works in Go using eBPF\",\n  \"order\": 2,\n  \"redirect_from\": [\"/tutorials/simple-go-tracing/\", \"/using-pixie/use-cases/code-tracing/\"]\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar YouTube = makeShortcode(\"YouTube\");\nvar CodeTabs = makeShortcode(\"CodeTabs\");\nvar CodeRenderer = makeShortcode(\"CodeRenderer\");\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"This is a simple demo showing the ability of Pixie to add dynamic structured logs into\\nGo binaries deployed in production environments. This capability allows one to debug Go\\nbinaries in production without the need\\nto instrument the source code with additional log statements, recompile, and redeploy.\"), mdx(\"p\", null, \"A simple overview of this functionality is show here:\"), mdx(\"div\", {\n    \"className\": \"image-l\"\n  }, mdx(\"svg\", {\n    title: \"Dynamic Structured Logging in Go\",\n    src: \"dynamic_logs.svg\"\n  })), mdx(\"p\", null, \"In a legacy systems a modify-compile-deploy cycle is required to get visibility into the binary\\nif the appropriate log lines are missing. Pixie allows\\nyou to dynamically capture function arguments, return values and latency, without this slow\\nprocess. Since we use new kernel technologies like eBPF, we can safely insert these logs without stopping\\nexecution of you program, and with minimal overhead.\"), mdx(\"p\", null, \"Note: Dynamic logging is an alpha feature.\\n\", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/tutorials/custom-data/dynamic-go-logging/#requirements-and-limitations\"\n  }), \"Limitations\"), \" are listed at the end of this page.\"), mdx(\"h2\", null, \"Tutorial Overview\"), mdx(YouTube, {\n    youTubeId: \"aH7PHSsiIPM\",\n    mdxType: \"YouTube\"\n  }), mdx(\"h2\", null, \"Setup\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Pixie needs to be installed on your Kubernetes cluster. If it is not already installed, please consult our \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/installing-pixie/\"\n  }), \"install guides\"), \".\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Clone the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pixie\"), \" repo to get the relevant files.\"))), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"git clone https://github.com/pixie-io/pixie-demos.git\\ncd pixie-demos/simple-gotracing\\n\"))))), mdx(\"h2\", null, \"Running the Demo\"), mdx(\"p\", null, \"The demo is completely self-contained and will install a simple Go application under the\\nnamespace px-demo-gotracing. The source of this application is in app.go. To deploy this application run:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"kubectl apply -f k8s_manifest.yaml\\n\"))))), mdx(\"p\", null, \"We are going to dynamic trace the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"computeE\"), \" function in app.go to get started. This is a simple function\\nthat tried to approximate the value of \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://en.wikipedia.org/wiki/E_(mathematical_constant)\"\n  }), \"eulers number\"), \" by\\nusing a taylor series. The number of iterations of the expansion is specified by the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"iters\"), \" query param to the HTTP handler.\\nTo see how this works we can connect to the service by forwarding the appropriate port:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"kubectl port-forward service/gotracing-svc -n px-demo-gotracing 9090\\n\"))))), mdx(\"p\", null, \"We can use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"curl\"), \" to quickly access the api. The number of iterations is the query parameter \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"iters\"), \".\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"curl http://localhost:9090/e\\n# e = 2.7183\\n\\ncurl http://localhost:9090/e\\\\?iters\\\\=2\\n# e = 2.0000\\n\\ncurl http://localhost:9090/e\\\\?iters\\\\=200\\n# e = 2.7183\\n\"))))), mdx(\"p\", null, \"As expected the accuracy of e approaches the expected value of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"2.7183\"), \" as we\\nincrease the number of iterations.\"), mdx(\"p\", null, \"The full source code of this is located here. The function that computes this is shown below:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"go\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-go\"\n  }), \"// computeE computes the approximation of e by running a fixed number of iterations.\\nfunc computeE(iterations int64) float64 {\\n    res := 2.0\\n    fact := 1.0\\n\\n    for i := int64(2); i < iterations; i++ {\\n        fact *= float64(i)\\n        res += 1 / fact\\n    }\\n    return res\\n}\\n\"))))), mdx(\"p\", null, \"The function computeE is called by an HTTP handler. Let's say we want to quickly access the arguments to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"computeE\"), \"\\nfunction, and it's latency. We can use the provided \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/pixie-io/pixie-demos/blob/main/simple-gotracing/capture_args.pxl\"\n  }), \"capture_args.pxl\"), \"\\nscript. The complete script has code to programmatically insert the log\\nand capture data for a time period. However, the actual function that captures this data is straightforward:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"python\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-python\"\n  }), \"@pxtrace.probe(\\\"main.computeE\\\")\\ndef probe_func():\\n    return [{\\n        'iterations': pxtrace.ArgExpr(\\\"iterations\\\"),\\n        'latency': pxtrace.FunctionLatency(),\\n    }]\\n\"))))), mdx(\"p\", null, \"This PXL function simply attached to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"main.computeE\"), \" function and grabs the iterations argument along with the\\nexecution time in nanoseconds.\"), mdx(\"p\", null, \"To attach this function to our running binary we need to first identify the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"UPID\"), \" of the process we want to trace. The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"UPID\"), \" refers to the \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"unique process id\"), \", which is a process ID that\\nis globally unique in the entire cluster. In future versions of Pixie we will make this process easier. For now, we can\\neasily get the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"UPID\"), \" by running the follow script:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"px run px/upids -- --namespace px-demo-gotracing\\n\\n# [0000]  INFO Pixie CLI\\n# Table ID: UPIDs\\n#   CLUSTERID                             POD                                           CONTAINER  UPID                                  CMDLINE  POD CREATE TIME\\n#   f890689b-299c-43fd-8d2a-b0c528a58393  px-demo-gotracing/gotracing-7cdd66f89d-khnss  app        00000003-0023-9267-0000-000008e60831  ./main   2020-08-09T20:39:34-07:00\\n\"))))), mdx(\"p\", null, \"The relevant \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"UPID\"), \" is in the fourth column. Edit the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"upid\"), \" variable in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"capture_args.pxl\"), \" script with this value. Alternatively, you can run the following\\nshell command that will do the substitution for you:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"sed -i'.orig' \\\"s/replace-me-with-upid/$(px run -o json px/upids -- --namespace px-demo-gotracing  | jq -r '.upid' | head -n 1)/g\\\" capture_args.pxl\\n\"))))), mdx(\"p\", null, \"Run the PxL script:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"px run -f capture_args.pxl\\n\\n# [0000]  INFO Pixie CLI\\n#  \\u2714    Preparing schema\\n#  \\u2714    Deploying compute_e_data\\n# Table ID: output\\n#   CLUSTERID    UPID  TIME   GOID   ITERATIONS\\n\"))))), mdx(\"p\", null, \"The result data will be empty since no requests have been made yet. Let's run the curl commands we have above and see what happens:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"px run -f capture_args.pxl\\n\\n# [0000]  INFO Pixie CLI\\n# Table ID: output\\n#   CLUSTERID                             UPID                                  TIME                       GOID    ITERATIONS\\n#   f890689b-299c-43fd-8d2a-b0c528a58393  00000003-0024-844a-0000-000008caa618  2020-08-09T17:16:11-07:00  194529  100\\n#   f890689b-299c-43fd-8d2a-b0c528a58393  00000003-0024-844a-0000-000008caa618  2020-08-09T17:16:14-07:00  194416  2\\n#   f890689b-299c-43fd-8d2a-b0c528a58393  00000003-0024-844a-0000-000008caa618  2020-08-09T17:16:16-07:00  194531  200\\n\"))))), mdx(\"p\", null, \"There it is, we just capture all the arguments to the computeE function without changing the source code or redeploying it. We also found out\\nthat the default number of iterations is a 100 without having to look through the source code. While this example is straight forward and simple\\nand hardly requires the use of dynamic logging to understand, we can easily see how this can be used to debug much more complicated scenarios.\"), mdx(\"h2\", null, \"Cleaning Up\"), mdx(\"p\", null, \"To delete the demo from the cluster just run:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"kubectl delete namespace px-demo-gotracing\\n\"))))), mdx(\"h2\", null, \"Modifying the Demo\"), mdx(\"h3\", null, \"Building and Deploying the App\"), mdx(\"p\", null, \"The demo can easily be modified by editing the app.go source file. After that you can simply create a new docker image by running:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"bash\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-bash\"\n  }), \"docker build . -t <image name>\\n\"))))), mdx(\"p\", null, \"Edit the image name in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"k8s_manifest.yaml\"), \" to correspond to you new image and redeploy.\"), mdx(\"h3\", null, \"Formatting the pxtrace.probe path\"), mdx(\"p\", null, \"The format of the probe path differs slightly depending on whether the function being traced is a standard function or a \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://tour.golang.org/methods/8\"\n  }), \"receiver method\"), \". To create the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pxtrace.probe path\"), \" follow these steps:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Get the package path (typically the directory of the file that contains the function) + prefix under GoSrc.\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Get the full function name. For simple functions (like the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"computeE\"), \" example above), this is simply the name of the function. For receiver methods, format as \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"(*<struct-name>).<funcName>\"), \".\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Combine together as \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<gopath>.<fullFuncName>\"), \". Note that if the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fullFuncName\"), \" is unambiguous, you may leave out the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gopath\"), \".\"))), mdx(\"h4\", null, \"Example Probe for a Regular Function\"), mdx(\"p\", null, \"To trace the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"encodeError\"), \" Go function from \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/microservices-demo/payment/blob/master/transport.go#L47\"\n  }), mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"https://github.com/microservices-demo/payment/blob/master/transport.go\")), \", with the following signature:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"go\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-go\"\n  }), \"func encodeError(_ context.Context, err error, w http.ResponseWriter) {}\\n\"))))), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Take the project path + package prefix from the top of the file: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"github.com/microservices-demo/payment\"), \" + \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"payment\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Take the function name: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"encodeError\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Combine these two parts together to get the full probe path. The resulting PxL script probe is:\"))), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"python\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-python\"\n  }), \"@pxtrace.probe(\\\"github.com/microservices-demo/payment/payment.encodeError\\\")\\n\"))))), mdx(\"h4\", null, \"Example Probe for a Struct Function\"), mdx(\"p\", null, \"To trace the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Authorise\"), \" receiver method from \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/microservices-demo/payment/blob/master/service.go#L41\"\n  }), mdx(\"inlineCode\", {\n    parentName: \"a\"\n  }, \"https://github.com/microservices-demo/payment/blob/master/service.go\")), \", with the following signature:\"), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"go\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-go\"\n  }), \"func (s *service) Authorise(amount float32) (Authorisation, error) {}\\n\"))))), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Take the project path + package prefix from the top of the file: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"github.com/microservices-demo/payment\"), \" + \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"payment\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Since it's a receiver method, the full method name would be formatted as: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"(*service).Authorise\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Combine these two parts together to get the full probe path. The resulting PxL script probe is:\"))), mdx(\"div\", {\n    \"className\": \"code-tabs-wrapper\"\n  }, mdx(CodeTabs, {\n    mdxType: \"CodeTabs\"\n  }, mdx(CodeRenderer, {\n    language: \"python\",\n    title: \"\",\n    mdxType: \"CodeRenderer\"\n  }, mdx(\"pre\", {\n    parentName: \"div\"\n  }, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-python\"\n  }), \"@pxtrace.probe(\\\"github.com/microservices-demo/payment/payment.(*service).Authorise\\\")\\n\"))))), mdx(\"h2\", null, \"Requirements & Limitations\"), mdx(\"p\", null, \"Dynamic logging is an alpha feature. It is currently only supports logging of Go binaries.\"), mdx(\"h3\", null, \"Requirements\"), mdx(\"p\", null, \"Dynamic Go Logging works using \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/reference/admin/debug-info\"\n  }), \"debug information\"), \". By default, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"go build\"), \" compiles your program with debug information and is compatible with Dynamic Go Logging. However, if you compile with -ldflags '-w -s' or strip the debug symbols after compiling, then you will not be able use Dynamic Go Logging.\"), mdx(\"p\", null, \"Additionally, Dynamic logging works for Golang versions up to 1.16 only (the go compiler for 1.17 changed the calling convention, and the Dynamic Logging feature has not yet been updated to support those changes).\"), mdx(\"h3\", null, \"Limitations\"), mdx(\"p\", null, \"Dynamic Logging can currently be used to trace only certain types of arguments and return values:\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Value type (argument or return value)\"), mdx(\"th\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Supported?\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Primitive types\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Yes.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Strings\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Yes. Truncated after 23 characters\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Arrays\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"No.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Structs\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Partial. Struct members that are other primitive types or other structs are traced. Pointers to other types are not followed. Strings inside structs are not supported.\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Interfaces\"), mdx(\"td\", _extends({\n    parentName: \"tr\"\n  }, {\n    \"align\": \"left\"\n  }), \"Partial. Struct data is printed out. If more than 128 types implement the same interface, then the interface is not traced.\")))), mdx(\"p\", null, \"If your build is optimized with inlining (-gcflags '-l'), certain functions won't be traceable.\\nFor more info see the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://golang.org/doc/gdb#Introduction\"\n  }), \"golang documentation\"), \".\"), mdx(\"h3\", null, \"Known Issues\"), mdx(\"p\", null, \"Note that there is a known bug in which re-running the script after modifying the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"probe_func\"), \" definition will cause the tracepoint to fail to deploy. To get around this bug, whenever you modify the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"probe_func\"), \" definition, please rename the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"table_name\"), \" (and update the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"table_name\"), \" in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"df = px.DataFrame(table_name)\"), \" line as well.\"));\n}\n;\nMDXContent.isMDXComponent = true;","parent":{"__typename":"File","relativePath":"en/04-tutorials/04-custom-data/02-dynamic-go-logging.md"},"frontmatter":{"metaTitle":"Tutorials | Collecting Custom Data | Dynamic Structured Logging In Go","metaDescription":"Simple tutorial to show how dynamic structured logging works in Go using eBPF"},"headings":[{"value":"Tutorial Overview","depth":2},{"value":"Setup","depth":2},{"value":"Running the Demo","depth":2},{"value":"Cleaning Up","depth":2},{"value":"Modifying the Demo","depth":2},{"value":"Building and Deploying the App","depth":3},{"value":"Formatting the pxtrace.probe path","depth":3},{"value":"Example Probe for a Regular Function","depth":4},{"value":"Example Probe for a Struct Function","depth":4},{"value":"Requirements & Limitations","depth":2},{"value":"Requirements","depth":3},{"value":"Limitations","depth":3},{"value":"Known Issues","depth":3}]},"allMdx":{"edges":[{"node":{"fields":{"slug":"/about-pixie","title":"About Pixie","level":1,"id":"250033c7-6bfc-5ed2-8855-bfae9d3d41b8","lang":"en"}}},{"node":{"fields":{"slug":"/about-pixie/what-is-pixie","title":"Pixie Overview","level":2,"id":"3d7111da-bb7e-58a6-acdb-af0bee4488fb","lang":"en"}}},{"node":{"fields":{"slug":"/about-pixie/data-sources","title":"Data Sources","level":2,"id":"ceef1554-49d1-5b10-a3fa-6dc84d90bf20","lang":"en"}}},{"node":{"fields":{"slug":"/about-pixie/pixie-ebpf","title":"How Pixie uses eBPF","level":2,"id":"5e9e1b8e-3181-52e0-a3d5-335a3367cb14","lang":"en"}}},{"node":{"fields":{"slug":"/about-pixie/roadmap","title":"Roadmap","level":2,"id":"15dcc722-a1a6-58e9-9c20-8d6f8d3762df","lang":"en"}}},{"node":{"fields":{"slug":"/about-pixie/faq","title":"FAQ","level":2,"id":"af60166c-104d-576d-8018-94d9907813f9","lang":"en"}}},{"node":{"fields":{"slug":"/about-pixie/troubleshooting","title":"Troubleshooting","level":2,"id":"739e15de-0d00-526a-80ed-51a13c2b6f5d","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie","title":"Installing Pixie","level":1,"id":"77fd1ffe-859b-5b56-9745-5c371bd47e6d","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/requirements","title":"Requirements","level":2,"id":"d3d8a31a-c579-5792-8e40-3076ae89d15e","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/setting-up-k8s","title":"Setting up Kubernetes (optional)","level":2,"id":"1b2c0456-0c8e-59f3-9859-73e664d277bc","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/setting-up-k8s/minikube-setup","title":"Minikube","level":3,"id":"8e37881c-b785-585f-9bf4-271d71297044","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/setting-up-k8s/eks-setup","title":"EKS","level":3,"id":"f9e46ba9-b438-5226-94c2-8c580311efb9","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/setting-up-k8s/gke-setup","title":"GKE","level":3,"id":"89fcc4ea-771a-5bdc-ae96-75fa080b2402","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/setting-up-k8s/aks-setup","title":"AKS","level":3,"id":"61a9efea-c52d-5b4a-ad01-7758292a1e6b","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/setting-up-k8s/k0s-setup","title":"k0s","level":3,"id":"db610fd7-59f7-50ee-b962-2395ded4213d","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/setting-up-k8s/other-environments","title":"Additional environments","level":3,"id":"456ab527-bcef-5f0b-9099-92524b0e1a60","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-guides","title":"Install Guides","level":2,"id":"f94cfa88-6add-5e46-86f8-7c89ad77886a","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-guides/hosted-pixie","title":"Hosted Pixie","level":3,"id":"e12f9502-f00b-5290-aabe-6952f1017919","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-guides/hosted-pixie/cosmic-cloud","title":"Cosmic Cloud","level":4,"id":"24145104-fa42-53e2-9cd4-207bc191da39","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-guides/hosted-pixie/new-relic-cloud","title":"New Relic Cloud","level":4,"id":"604f4893-db3e-5b9a-86a0-d487039b117b","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-guides/self-hosted-pixie","title":"Self-Hosted Pixie","level":3,"id":"60ea09cc-b8c7-52d5-b3f6-da39d78b8014","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-guides/self-hosted-pixie/airgap-pixie","title":"Air Gapped Pixie","level":4,"id":"2e215d50-3936-58fa-bc7e-7b9d56205705","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-guides/self-hosted-pixie/production-readiness","title":"Production Readiness","level":4,"id":"4bba186e-a4e9-52f9-a556-3367c6beb3cf","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-schemes","title":"Install Schemes (optional)","level":2,"id":"89aa8fa5-88de-57fa-ac9b-9d9cb4680190","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-schemes/cli","title":"CLI (Recommended)","level":3,"id":"c180d499-3bbe-5b18-aca2-fad92744f82b","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-schemes/yaml","title":"YAML","level":3,"id":"a07677ae-cdce-581a-a639-b2c6eb63ca2a","lang":"en"}}},{"node":{"fields":{"slug":"/installing-pixie/install-schemes/helm","title":"Helm","level":3,"id":"198fca51-0df6-5a68-82bc-c33777f6c452","lang":"en"}}},{"node":{"fields":{"slug":"/using-pixie","title":"Using Pixie","level":1,"id":"ee5c081e-d25d-50ac-b534-b26089cb7fa9","lang":"en"}}},{"node":{"fields":{"slug":"/using-pixie/using-live-ui","title":"Using the Live UI","level":2,"id":"f6358be5-5e72-5d5a-b802-37b7a1832a6e","lang":"en"}}},{"node":{"fields":{"slug":"/using-pixie/using-cli","title":"Using the CLI","level":2,"id":"68df7159-bf22-5cfe-8a81-1376fc49fe9e","lang":"en"}}},{"node":{"fields":{"slug":"/using-pixie/api-quick-start","title":"Using the API","level":2,"id":"1dc6c347-8d39-5536-8bdb-6c8b9a3c9cab","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials","title":"Tutorials","level":1,"id":"cca4356e-0565-5dcf-b2e0-80aa8b361993","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pixie-101","title":"Pixie 101","level":2,"id":"33c94a0b-7e15-50de-9749-c25f7cef4839","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pixie-101/network-monitoring","title":"Network Monitoring","level":3,"id":"07ab17ed-445b-56bb-a95a-03c2c4643606","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pixie-101/infra-health","title":"Infra Health","level":3,"id":"7d14f277-00f4-53bf-b4a0-8deb32615831","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pixie-101/service-performance","title":"Service Performance","level":3,"id":"b9843b3b-9061-5df8-bb5b-20a96ab7516b","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pixie-101/database-query-profiling","title":"Database Query Profiling","level":3,"id":"15b9c87a-215a-554b-9a09-3c4013e68e01","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pixie-101/request-tracing","title":"Request Tracing","level":3,"id":"e940076b-02be-5f2d-b951-6fa2fc5e430d","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pixie-101/profiler","title":"Continuous Application Profiling","level":3,"id":"9511d5a0-5e74-5165-9383-0fd475c23475","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pixie-101/kafka-monitoring","title":"Kafka Monitoring","level":3,"id":"2c806ace-110b-5395-a5b4-51d19005e151","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts","title":"PxL Scripts","level":2,"id":"78bb61b8-0d24-5d1a-9c05-acc2e750e2a7","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/write-pxl-scripts","title":"How to Write a PxL Script","level":3,"id":"8676a620-9a59-5bd0-9b53-55e63802b395","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-1","title":"Tutorial #1: Write your first PxL script","level":4,"id":"5caa0251-970d-57e2-9c04-ff6c61fbdca5","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-2","title":"Tutorial #2: Finish your first PxL Script","level":4,"id":"303904f6-8f98-5e43-8679-9d19bf0a0945","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-3","title":"Tutorial #3: Write your first Vis Spec","level":4,"id":"895dc65f-6f9e-5a8c-8d4e-368116926e91","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-4","title":"Tutorial #4: Add a Timeseries chart to your Vis Spec","level":4,"id":"2b04efb0-129d-5df3-9a4c-e61d87190077","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-5","title":"Tutorial #5: Add a Graph to your Vis Spec","level":4,"id":"9d89ab55-95d1-5a65-b88b-ed7e69f76eec","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/script-dev-environment","title":"Running the Script Dev Environment","level":3,"id":"a6251ead-6888-55c8-8ff2-b71355e973ea","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/script-of-the-week","title":"Script of the Week","level":3,"id":"6200e2ac-1b2d-5f58-8b02-d525503ca923","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/script-of-the-week/script-of-the-week-1","title":"SOTW #1: Network Flow Graph","level":4,"id":"eb9f1a63-f0bd-52ef-a481-4d239616af30","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/pxl-scripts/script-of-the-week/script-of-the-week-2","title":"SOTW #2: Detect redundant DNS requests caused by dnsConfig ndots setting","level":4,"id":"22e7fd79-7750-5f13-a21d-3d540a2c5c36","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/integrations","title":"Integrations and Alerts","level":2,"id":"fe423431-b224-5d0c-a88c-1f098066ccdf","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/integrations/slackbot-alert","title":"Slack Alerts using the Pixie API","level":3,"id":"1dc3e45e-b259-5d77-9bf3-3d4314cdb2eb","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/integrations/grafana","title":"Grafana Pixie Plugin","level":3,"id":"85eccf7d-3ec9-5511-ab5b-fa3e71725aa8","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/integrations/otel","title":"Export OpenTelemetry Data","level":3,"id":"4bab7cd9-681d-56d1-af53-de68b5b60dad","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/integrations/export-plugin","title":"Exporting PxL Scripts to a Plugin","level":3,"id":"eb57fb2e-c348-542c-98f1-655c88d3348b","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/custom-data","title":"Collecting Custom Data","level":2,"id":"ca5b9e99-5f1c-5ed4-93be-ebcf31699399","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/custom-data/distributed-bpftrace-deployment","title":"Distributed bpftrace Deployment","level":3,"id":"f1e1cc7a-5581-5676-8d9a-85bb14c52ce3","lang":"en"}}},{"node":{"fields":{"slug":"/tutorials/custom-data/dynamic-go-logging","title":"Dynamic Logging In Go (Alpha)","level":3,"id":"b1fa96bb-c032-5c32-bbd3-9d1dc00cb3e3","lang":"en"}}},{"node":{"fields":{"slug":"/reference","title":"Reference","level":1,"id":"972efda6-5ba8-5c1f-b409-e1961e60a697","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin","title":"Admin","level":2,"id":"e8b2b842-2589-5519-894a-95851f06ed1b","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/authentication","title":"Authentication","level":3,"id":"023db48c-efc1-5556-8428-f1b25a98b853","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/debug-info","title":"Debug Info","level":3,"id":"e334c6f5-0f9b-59b4-bd49-d79574c7a6d0","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/deploy-options","title":"Deploy Options","level":3,"id":"332629cf-447a-523d-97d5-9ecf5635adfb","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/environment-configs","title":"Environment-Specific Configurations","level":3,"id":"646bc1aa-e534-50a0-adf9-df13592f40da","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/cluster-id","title":"Find a Cluster ID","level":3,"id":"a8f5bac8-c7b4-5985-abcd-7ebb6a897673","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/api-keys","title":"Managing API Keys","level":3,"id":"589063fb-21f2-5877-aed8-b3673fcaecc5","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/deploy-keys","title":"Managing Deploy Keys","level":3,"id":"d1ce062f-9be2-5b3e-898a-08590163e618","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/tuning-mem-usage","title":"Tuning Memory Usage","level":3,"id":"5d943cc7-00cd-55fd-b465-e60961155dea","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/uninstall","title":"Uninstalling Pixie","level":3,"id":"95a9ed92-2b71-5f32-9618-398ffbe1aeca","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/updating-pixie","title":"Updating Pixie","level":3,"id":"02982707-1c80-570f-b226-aa46207feace","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/user-mgmt","title":"User Management & Sharing","level":3,"id":"3cc5d4b2-6779-5a7b-a1a1-690511981cf5","lang":"en"}}},{"node":{"fields":{"slug":"/reference/admin/verifying-images","title":"Verifying Images","level":3,"id":"4b741c31-3593-516e-b388-dec7288b2fd7","lang":"en"}}},{"node":{"fields":{"slug":"/reference/architecture","title":"Architecture","level":2,"id":"44dca647-e9a1-578f-b4a4-fdc40eeb46b2","lang":"en"}}},{"node":{"fields":{"slug":"/reference/api","title":"API","level":2,"id":"a144a102-4502-574a-9734-6d5463354591","lang":"en"}}},{"node":{"fields":{"slug":"/reference/api/overview","title":"Overview","level":3,"id":"546c5a9f-b1d7-5286-8f7d-47e2fd3c6535","lang":"en"}}},{"node":{"fields":{"slug":"/reference/api/go","title":"Go","level":3,"id":"7194578f-2940-5669-b681-7a7aa29378ce","lang":"en"}}},{"node":{"fields":{"slug":"/reference/plugins","title":"Plugins","level":2,"id":"be267788-7808-5c2f-a868-289b64556b88","lang":"en"}}},{"node":{"fields":{"slug":"/reference/plugins/plugin-system","title":"Pixie Plugin System","level":3,"id":"b687eff3-307a-53c9-bf8b-a3247293a0f9","lang":"en"}}},{"node":{"fields":{"slug":"/reference/plugins/grafana","title":"Grafana Datasource Plugin","level":3,"id":"ae420e44-f30e-5686-be06-61b609233a11","lang":"en"}}},{"node":{"fields":{"slug":"/reference/pxl","title":"PxL","level":2,"id":"e07ac997-01a5-5a7c-9689-52a6cf481c7a","lang":"en"}}}]}},"pageContext":{"id":"b1fa96bb-c032-5c32-bbd3-9d1dc00cb3e3","lang":"en","languages":[{"id":"de","label":"Deutsch"}],"globalUrlTree":[{"lang":"en","slug":"/about-pixie/what-is-pixie"},{"lang":"en","slug":"/about-pixie/pixie-ebpf"},{"lang":"en","slug":"/about-pixie/data-sources"},{"lang":"en","slug":"/about-pixie/faq"},{"lang":"en","slug":"/about-pixie/roadmap"},{"lang":"en","slug":"/about-pixie"},{"lang":"en","slug":"/about-pixie/troubleshooting"},{"lang":"en","slug":"/installing-pixie"},{"lang":"en","slug":"/installing-pixie/requirements"},{"lang":"en","slug":"/using-pixie"},{"lang":"en","slug":"/using-pixie/api-quick-start"},{"lang":"en","slug":"/tutorials"},{"lang":"en","slug":"/reference"},{"lang":"en","slug":"/using-pixie/using-cli"},{"lang":"en","slug":"/using-pixie/using-live-ui"},{"lang":"en","slug":"/installing-pixie/setting-up-k8s/minikube-setup"},{"lang":"en","slug":"/installing-pixie/setting-up-k8s/eks-setup"},{"lang":"en","slug":"/installing-pixie/setting-up-k8s/gke-setup"},{"lang":"en","slug":"/installing-pixie/setting-up-k8s/other-environments"},{"lang":"en","slug":"/reference/architecture"},{"lang":"en","slug":"/installing-pixie/setting-up-k8s/k0s-setup"},{"lang":"en","slug":"/installing-pixie/setting-up-k8s/aks-setup"},{"lang":"en","slug":"/installing-pixie/setting-up-k8s"},{"lang":"en","slug":"/installing-pixie/install-guides"},{"lang":"en","slug":"/installing-pixie/install-schemes/cli"},{"lang":"en","slug":"/installing-pixie/install-schemes/helm"},{"lang":"en","slug":"/installing-pixie/install-schemes/yaml"},{"lang":"en","slug":"/installing-pixie/install-schemes"},{"lang":"en","slug":"/tutorials/pixie-101/network-monitoring"},{"lang":"en","slug":"/tutorials/pixie-101/infra-health"},{"lang":"en","slug":"/tutorials/pixie-101/service-performance"},{"lang":"en","slug":"/tutorials/pixie-101/request-tracing"},{"lang":"en","slug":"/tutorials/pixie-101/database-query-profiling"},{"lang":"en","slug":"/tutorials/pixie-101/kafka-monitoring"},{"lang":"en","slug":"/tutorials/pixie-101"},{"lang":"en","slug":"/tutorials/pxl-scripts"},{"lang":"en","slug":"/tutorials/pxl-scripts/script-dev-environment"},{"lang":"en","slug":"/tutorials/pixie-101/profiler"},{"lang":"en","slug":"/tutorials/integrations/slackbot-alert"},{"lang":"en","slug":"/tutorials/integrations"},{"lang":"en","slug":"/tutorials/integrations/export-plugin"},{"lang":"en","slug":"/tutorials/custom-data"},{"lang":"en","slug":"/tutorials/custom-data/dynamic-go-logging"},{"lang":"en","slug":"/reference/admin/authentication"},{"lang":"en","slug":"/reference/admin/debug-info"},{"lang":"en","slug":"/reference/admin/cluster-id"},{"lang":"en","slug":"/tutorials/custom-data/distributed-bpftrace-deployment"},{"lang":"en","slug":"/tutorials/integrations/grafana"},{"lang":"en","slug":"/tutorials/integrations/otel"},{"lang":"en","slug":"/reference/admin/environment-configs"},{"lang":"en","slug":"/reference/admin/api-keys"},{"lang":"en","slug":"/reference/admin/deploy-keys"},{"lang":"en","slug":"/reference/admin/deploy-options"},{"lang":"en","slug":"/reference/admin/verifying-images"},{"lang":"en","slug":"/reference/api/overview"},{"lang":"en","slug":"/reference/admin/tuning-mem-usage"},{"lang":"en","slug":"/reference/api/go"},{"lang":"en","slug":"/reference/admin/user-mgmt"},{"lang":"en","slug":"/reference/admin"},{"lang":"en","slug":"/reference/admin/updating-pixie"},{"lang":"en","slug":"/reference/api"},{"lang":"en","slug":"/reference/plugins/grafana"},{"lang":"en","slug":"/reference/plugins/plugin-system"},{"lang":"en","slug":"/reference/admin/uninstall"},{"lang":"en","slug":"/installing-pixie/install-guides/hosted-pixie/cosmic-cloud"},{"lang":"en","slug":"/reference/plugins"},{"lang":"en","slug":"/reference/pxl"},{"lang":"en","slug":"/installing-pixie/install-guides/hosted-pixie/new-relic-cloud"},{"lang":"en","slug":"/installing-pixie/install-guides/hosted-pixie"},{"lang":"en","slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-3"},{"lang":"en","slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-1"},{"lang":"en","slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-4"},{"lang":"en","slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-2"},{"lang":"en","slug":"/tutorials/pxl-scripts/write-pxl-scripts/custom-pxl-scripts-5"},{"lang":"en","slug":"/installing-pixie/install-guides/self-hosted-pixie/production-readiness"},{"lang":"en","slug":"/installing-pixie/install-guides/self-hosted-pixie/airgap-pixie"},{"lang":"en","slug":"/installing-pixie/install-guides/self-hosted-pixie"},{"lang":"en","slug":"/tutorials/pxl-scripts/write-pxl-scripts"},{"lang":"en","slug":"/tutorials/pxl-scripts/script-of-the-week/script-of-the-week-1"},{"lang":"en","slug":"/tutorials/pxl-scripts/script-of-the-week"},{"lang":"en","slug":"/tutorials/pxl-scripts/script-of-the-week/script-of-the-week-2"}],"availableLanguages":[{"slug":"/tutorials/custom-data/dynamic-go-logging","lang":"en"}],"availableClouds":[{"name":"Cosmic Cloud","baseUrl":"https://work.getcosmic.ai","cloudAddr":"getcosmic.ai"},{"name":"New Relic Cloud","baseUrl":"https://work.withpixie.ai","cloudAddr":"withpixie.ai"}]}}}