├── .gitattributes ├── .gitignore ├── .nojekyll ├── LICENSE ├── README.md ├── argo-rollouts-demo ├── .readme_assets │ ├── analysisrun-output.png │ ├── front-end.png │ ├── successful-front-end.png │ ├── successful-rollout-complete.png │ ├── successful-rollout.png │ ├── unsuccessful-front-end.png │ └── unsuccessful-rollout-complete.png ├── README.md ├── canary │ ├── canary-preview-service.yaml │ ├── canary-service.yaml │ ├── pixie-analysis.yaml │ └── rollout-with-analysis.yaml ├── kustomization.yaml ├── px-metrics.yaml └── px_metrics_server │ ├── Dockerfile │ ├── go.mod │ ├── go.sum │ └── pixie-metric-server.go ├── custom-k8s-metrics-demo ├── Dockerfile ├── README.md ├── demo-app.yaml ├── go.mod ├── go.sum ├── main.go ├── pixie-http-metric-provider.go ├── px-custom-metrics.yaml └── pxl │ ├── pods.pxl │ └── vis.json ├── data-exfiltration-demo ├── Dockerfile ├── README.md ├── demo.yaml ├── go.mod ├── go.sum └── main.go ├── detect-monero-demo ├── Dockerfile ├── README.md ├── detectrandomx.bt ├── detectrandomx.pxl └── xmrig_deployment.yaml ├── ebpf-profiler ├── Makefile ├── README.md ├── perf_profiler.cc ├── perf_profiler_bpf_funcs.c ├── perf_profiler_types.h └── toy_app │ └── sqrt.go ├── eks-workshop ├── README.md ├── clusterconfig.yaml └── complete-demo.yaml ├── endpoint-deprecation ├── .readme_assets │ ├── service_endpoint_requests.png │ ├── service_endpoints_summary.png │ └── unique_req_header_values.png ├── README.md ├── demo-app.yaml ├── service_endpoint_requests │ ├── manifest.yaml │ ├── service_endpoint_requests.pxl │ └── vis.json ├── service_endpoints_summary │ ├── manifest.yaml │ ├── service_endpoints_summary.pxl │ └── vis.json ├── service_requests │ ├── manifest.yaml │ ├── service_requests.pxl │ └── vis.json └── unique_req_header_values │ ├── manifest.yaml │ ├── unique_req_header_values.pxl │ └── vis.json ├── go-garbage-collector ├── .readme_assets │ ├── gc_events.png │ └── sweep.png ├── Dockerfile ├── README.md ├── demo-app.yaml ├── go.mod ├── main.go └── pxl_scripts │ ├── uprobe_scripts │ ├── GC.pxl │ ├── _canary_probe.pxl │ ├── allocSpan.pxl │ ├── gcAssistAlloc1.pxl │ ├── gcDrainN.pxl │ ├── gcSetTriggerRatio.pxl │ ├── gcSweep.pxl │ ├── gcWaitOnMark.pxl │ ├── startTheWorldWithSema.pxl │ ├── stopTheWorldWithSema.pxl │ └── sweepone.pxl │ └── visualization │ ├── vis.json │ └── visualize_gc.pxl ├── http2-tracing ├── .readme_assets │ ├── http2_header_lookup_table.png │ ├── uprobe_tracer_output.png │ ├── wireshark_http2_headers.png │ ├── wireshark_http2_headers_failed.png │ ├── wireshark_http2_setting.png │ └── wireshark_packets.png ├── README.md ├── client │ └── main.go ├── go.mod ├── go.sum ├── proto │ ├── greet.proto │ └── greetpb │ │ ├── greet.pb.go │ │ └── greet_grpc.pb.go ├── server │ └── main.go └── uprobe_trace │ ├── bpf_program.go │ └── http2_trace_uprobe.go ├── index.html ├── k8s-cost-estimation ├── .readme_assets │ └── cost_per_request.png ├── README.md ├── cost_per_request.pxl ├── cpu_cost.pxl ├── mem_cost.pxl └── network_cost.pxl ├── openssl-tracer ├── Makefile ├── README.md ├── openssl_tracer.cc ├── openssl_tracer_bpf_funcs.c ├── openssl_tracer_types.h ├── probe_deployment.cc ├── probe_deployment.h └── ssl_client_server │ ├── Makefile │ ├── client.py │ └── server.py ├── otel-collector ├── README.md └── collector.yaml ├── react-table ├── .nojekyll ├── 1-basics │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ ├── robots.txt │ │ └── static │ │ │ ├── css │ │ │ ├── main.5b9e8232.chunk.css │ │ │ └── main.5b9e8232.chunk.css.map │ │ │ └── js │ │ │ ├── 2.9033903f.chunk.js │ │ │ ├── 2.9033903f.chunk.js.LICENSE.txt │ │ │ ├── 2.9033903f.chunk.js.map │ │ │ ├── 3.ab8d20b9.chunk.js │ │ │ ├── 3.ab8d20b9.chunk.js.map │ │ │ ├── main.fd5d59cd.chunk.js │ │ │ ├── main.fd5d59cd.chunk.js.map │ │ │ ├── runtime-main.3b1ab93e.js │ │ │ └── runtime-main.3b1ab93e.js.map │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── Table.js │ │ ├── Table.module.css │ │ ├── index.css │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ └── useData.js ├── 2-react-table │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ ├── robots.txt │ │ └── static │ │ │ ├── css │ │ │ ├── main.42c8a56d.chunk.css │ │ │ └── main.42c8a56d.chunk.css.map │ │ │ └── js │ │ │ ├── 2.7fa4c899.chunk.js │ │ │ ├── 2.7fa4c899.chunk.js.LICENSE.txt │ │ │ ├── 2.7fa4c899.chunk.js.map │ │ │ ├── 3.22ca2655.chunk.js │ │ │ ├── 3.22ca2655.chunk.js.map │ │ │ ├── main.87594b58.chunk.js │ │ │ ├── main.87594b58.chunk.js.map │ │ │ ├── runtime-main.d56450fc.js │ │ │ └── runtime-main.d56450fc.js.map │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── Table.js │ │ ├── Table.module.css │ │ ├── index.css │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ └── useData.js ├── 3-sort-and-filter │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ ├── robots.txt │ │ └── static │ │ │ ├── css │ │ │ ├── main.d666c1a7.chunk.css │ │ │ └── main.d666c1a7.chunk.css.map │ │ │ └── js │ │ │ ├── 2.612c659f.chunk.js │ │ │ ├── 2.612c659f.chunk.js.LICENSE.txt │ │ │ ├── 2.612c659f.chunk.js.map │ │ │ ├── 3.f684159d.chunk.js │ │ │ ├── 3.f684159d.chunk.js.map │ │ │ ├── main.0c402462.chunk.js │ │ │ ├── main.0c402462.chunk.js.map │ │ │ ├── runtime-main.298b9c6d.js │ │ │ └── runtime-main.298b9c6d.js.map │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── Filter.js │ │ ├── Filter.module.css │ │ ├── Table.js │ │ ├── Table.module.css │ │ ├── index.css │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ └── useData.js ├── 4-column-controls │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ ├── robots.txt │ │ └── static │ │ │ ├── css │ │ │ ├── main.611aeaed.chunk.css │ │ │ └── main.611aeaed.chunk.css.map │ │ │ └── js │ │ │ ├── 2.ce919d20.chunk.js │ │ │ ├── 2.ce919d20.chunk.js.LICENSE.txt │ │ │ ├── 2.ce919d20.chunk.js.map │ │ │ ├── 3.acf92f0f.chunk.js │ │ │ ├── 3.acf92f0f.chunk.js.map │ │ │ ├── main.df0ba673.chunk.js │ │ │ ├── main.df0ba673.chunk.js.map │ │ │ ├── runtime-main.9d7ab708.js │ │ │ └── runtime-main.9d7ab708.js.map │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── ColumnSelector.js │ │ ├── ColumnSelector.module.css │ │ ├── Filter.js │ │ ├── Filter.module.css │ │ ├── Table.js │ │ ├── Table.module.css │ │ ├── index.css │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ └── useData.js ├── 5-fancy-cells │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ ├── robots.txt │ │ └── static │ │ │ ├── css │ │ │ ├── main.13a31467.chunk.css │ │ │ └── main.13a31467.chunk.css.map │ │ │ └── js │ │ │ ├── 2.6db881a1.chunk.js │ │ │ ├── 2.6db881a1.chunk.js.LICENSE.txt │ │ │ ├── 2.6db881a1.chunk.js.map │ │ │ ├── 3.acf92f0f.chunk.js │ │ │ ├── 3.acf92f0f.chunk.js.map │ │ │ ├── main.310358aa.chunk.js │ │ │ ├── main.310358aa.chunk.js.map │ │ │ ├── runtime-main.5a2cac45.js │ │ │ └── runtime-main.5a2cac45.js.map │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── ColumnSelector.js │ │ ├── ColumnSelector.module.css │ │ ├── Filter.js │ │ ├── Filter.module.css │ │ ├── Table.js │ │ ├── Table.module.css │ │ ├── index.css │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ └── useData.js ├── 6-new-base │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ ├── robots.txt │ │ └── static │ │ │ ├── css │ │ │ ├── main.99c788ec.chunk.css │ │ │ └── main.99c788ec.chunk.css.map │ │ │ └── js │ │ │ ├── 2.11d22c4e.chunk.js │ │ │ ├── 2.11d22c4e.chunk.js.LICENSE.txt │ │ │ ├── 2.11d22c4e.chunk.js.map │ │ │ ├── 3.e7c438f0.chunk.js │ │ │ ├── 3.e7c438f0.chunk.js.map │ │ │ ├── main.8d5fe1bc.chunk.js │ │ │ ├── main.8d5fe1bc.chunk.js.map │ │ │ ├── runtime-main.69a857c1.js │ │ │ └── runtime-main.69a857c1.js.map │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── ColumnSelector.js │ │ ├── ColumnSelector.module.css │ │ ├── Filter.js │ │ ├── Filter.module.css │ │ ├── Table.css │ │ ├── Table.js │ │ ├── Table.module.css │ │ ├── index.css │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ └── useData.js ├── 7-virtual-scrolling │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ ├── robots.txt │ │ └── static │ │ │ ├── css │ │ │ ├── main.aa168c71.chunk.css │ │ │ └── main.aa168c71.chunk.css.map │ │ │ └── js │ │ │ ├── 2.abf91ae0.chunk.js │ │ │ ├── 2.abf91ae0.chunk.js.LICENSE.txt │ │ │ ├── 2.abf91ae0.chunk.js.map │ │ │ ├── 3.532f84a7.chunk.js │ │ │ ├── 3.532f84a7.chunk.js.map │ │ │ ├── main.e0c0b0cc.chunk.js │ │ │ ├── main.e0c0b0cc.chunk.js.map │ │ │ ├── runtime-main.3fbad986.js │ │ │ └── runtime-main.3fbad986.js.map │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── ColumnSelector.js │ │ ├── ColumnSelector.module.css │ │ ├── Filter.js │ │ ├── Filter.module.css │ │ ├── Table.js │ │ ├── Table.module.css │ │ ├── index.css │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ ├── useContainerSize.js │ │ ├── useData.css │ │ ├── useData.js │ │ └── useScrollbarSize.js ├── 8-streaming-data │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ ├── robots.txt │ │ └── static │ │ │ ├── css │ │ │ ├── main.240826cc.chunk.css │ │ │ └── main.240826cc.chunk.css.map │ │ │ └── js │ │ │ ├── 2.11302f19.chunk.js │ │ │ ├── 2.11302f19.chunk.js.LICENSE.txt │ │ │ ├── 2.11302f19.chunk.js.map │ │ │ ├── 3.656f3982.chunk.js │ │ │ ├── 3.656f3982.chunk.js.map │ │ │ ├── main.49cdad53.chunk.js │ │ │ ├── main.49cdad53.chunk.js.map │ │ │ ├── runtime-main.eed26c3e.js │ │ │ └── runtime-main.eed26c3e.js.map │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── ColumnSelector.js │ │ ├── ColumnSelector.module.css │ │ ├── Filter.js │ │ ├── Filter.module.css │ │ ├── Table.js │ │ ├── Table.module.css │ │ ├── index.css │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ ├── useContainerSize.js │ │ ├── useData.css │ │ ├── useData.js │ │ └── useScrollbarSize.js ├── README.md ├── index.html └── react-table.code-workspace ├── simple-gotracing ├── .gitignore ├── Readme.md ├── app │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── app.go │ └── k8s_manifest.yaml ├── capture_args.pxl ├── go.mod ├── go.sum ├── http_trace_kprobe │ ├── .gitignore │ ├── Makefile │ ├── bpf_program.go │ └── http_trace_kprobe.go ├── http_trace_uprobe │ ├── .gitignore │ ├── Makefile │ ├── bpf_program.go │ ├── http_trace_uprobe.go │ └── utils.go └── trace_example │ ├── .gitignore │ ├── Makefile │ ├── Readme.md │ └── trace.go ├── slack-alert-app ├── README.md ├── go │ ├── go.mod │ ├── go.sum │ ├── http_errors.pxl │ └── slackbot.go └── python │ ├── http_errors.pxl │ ├── requirements.txt │ └── slackbot.py └── sql-injection-demo ├── README.md ├── dvwa-k8s └── web_deployment.yaml ├── script ├── sql_injections.pxl └── vis.json └── slackbot ├── requirements.txt ├── slackbot.py └── sql_injections.pxl /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pxl linguist-language=python -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | 3 | # Binaries for programs and plugins 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | # Test binary, built with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Dependency directories (remove the comment below to include it) 17 | # vendor/ 18 | 19 | custom-k8s-metrics-demo/main -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/.nojekyll -------------------------------------------------------------------------------- /argo-rollouts-demo/.readme_assets/analysisrun-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/argo-rollouts-demo/.readme_assets/analysisrun-output.png -------------------------------------------------------------------------------- /argo-rollouts-demo/.readme_assets/front-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/argo-rollouts-demo/.readme_assets/front-end.png -------------------------------------------------------------------------------- /argo-rollouts-demo/.readme_assets/successful-front-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/argo-rollouts-demo/.readme_assets/successful-front-end.png -------------------------------------------------------------------------------- /argo-rollouts-demo/.readme_assets/successful-rollout-complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/argo-rollouts-demo/.readme_assets/successful-rollout-complete.png -------------------------------------------------------------------------------- /argo-rollouts-demo/.readme_assets/successful-rollout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/argo-rollouts-demo/.readme_assets/successful-rollout.png -------------------------------------------------------------------------------- /argo-rollouts-demo/.readme_assets/unsuccessful-front-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/argo-rollouts-demo/.readme_assets/unsuccessful-front-end.png -------------------------------------------------------------------------------- /argo-rollouts-demo/.readme_assets/unsuccessful-rollout-complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/argo-rollouts-demo/.readme_assets/unsuccessful-rollout-complete.png -------------------------------------------------------------------------------- /argo-rollouts-demo/canary/canary-preview-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: canary-demo-preview 5 | spec: 6 | type: LoadBalancer 7 | ports: 8 | - port: 80 9 | targetPort: http 10 | protocol: TCP 11 | name: http 12 | selector: 13 | app: canary-demo 14 | -------------------------------------------------------------------------------- /argo-rollouts-demo/canary/canary-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: canary-demo 5 | spec: 6 | type: LoadBalancer 7 | ports: 8 | - port: 80 9 | targetPort: http 10 | protocol: TCP 11 | name: http 12 | selector: 13 | app: canary-demo 14 | -------------------------------------------------------------------------------- /argo-rollouts-demo/canary/pixie-analysis.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AnalysisTemplate 3 | metadata: 4 | name: http-error-rate-background 5 | spec: 6 | args: 7 | - name: service-name 8 | - name: namespace 9 | - name: canary-pod-hash 10 | metrics: 11 | - name: webmetric 12 | successCondition: result <= 0.05 13 | interval: 30s 14 | initialDelay: 30s 15 | provider: 16 | web: 17 | url: "http://px-metrics.px-metrics.svc.cluster.local/error-rate/{{args.namespace}}/{{args.service-name}}-{{args.canary-pod-hash}}" 18 | timeoutSeconds: 20 19 | jsonPath: "{$.error_rate}" 20 | -------------------------------------------------------------------------------- /argo-rollouts-demo/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - canary/rollout-with-analysis.yaml 6 | - canary/pixie-analysis.yaml 7 | - canary/canary-service.yaml 8 | - canary/canary-preview-service.yaml 9 | -------------------------------------------------------------------------------- /argo-rollouts-demo/px-metrics.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | labels: 6 | name: px-metrics 7 | name: px-metrics 8 | namespace: px-metrics 9 | spec: 10 | selector: 11 | matchLabels: 12 | name: px-metrics 13 | template: 14 | metadata: 15 | labels: 16 | name: px-metrics 17 | plane: control 18 | spec: 19 | containers: 20 | - name: app 21 | image: gcr.io/pixie-oss/pixie-dev/demo/argo-rollouts-demo:latest 22 | env: 23 | - name: PX_CLOUD_ADDR 24 | value: withpixie.ai:443 25 | - name: PX_CLUSTER_ID 26 | valueFrom: 27 | secretKeyRef: 28 | name: px-credentials 29 | key: px-cluster-id 30 | - name: PX_API_KEY 31 | valueFrom: 32 | secretKeyRef: 33 | name: px-credentials 34 | key: px-api-key 35 | ports: 36 | - containerPort: 8080 37 | --- 38 | apiVersion: v1 39 | kind: Service 40 | metadata: 41 | labels: 42 | name: px-metrics 43 | name: px-metrics 44 | namespace: px-metrics 45 | spec: 46 | ports: 47 | - port: 80 48 | targetPort: 8080 49 | selector: 50 | name: px-metrics 51 | -------------------------------------------------------------------------------- /argo-rollouts-demo/px_metrics_server/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM golang:1.16-alpine 4 | 5 | WORKDIR /app 6 | 7 | COPY go.mod ./ 8 | COPY go.sum ./ 9 | RUN go mod download 10 | 11 | COPY *.go ./ 12 | 13 | RUN go build -o /adapter 14 | 15 | EXPOSE 8080 16 | 17 | CMD ["/adapter", "--logtostderr=true"] 18 | -------------------------------------------------------------------------------- /argo-rollouts-demo/px_metrics_server/go.mod: -------------------------------------------------------------------------------- 1 | module pixielabs.ai/argo-rollouts-demo 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/julienschmidt/httprouter v1.3.0 7 | px.dev/pxapi v0.2.1 8 | ) 9 | -------------------------------------------------------------------------------- /custom-k8s-metrics-demo/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM golang:1.16-alpine 4 | 5 | WORKDIR /app 6 | 7 | COPY go.mod ./ 8 | COPY go.sum ./ 9 | RUN go mod download 10 | 11 | COPY *.go ./ 12 | 13 | RUN go build -o /adapter 14 | 15 | EXPOSE 8080 16 | 17 | CMD ["/adapter", "--logtostderr=true"] 18 | -------------------------------------------------------------------------------- /data-exfiltration-demo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.17 2 | 3 | WORKDIR /app 4 | 5 | 6 | COPY go.mod go.sum ./ 7 | RUN go mod download 8 | 9 | COPY *.go ./ 10 | 11 | RUN go build -o /data-exfiltration 12 | 13 | EXPOSE 8080 14 | 15 | CMD ["/data-exfiltration"] 16 | -------------------------------------------------------------------------------- /data-exfiltration-demo/README.md: -------------------------------------------------------------------------------- 1 | Requirements: 2 | - You need a k8s cluster capable of running Pixie (see [here](https://docs.px.dev/installing-pixie/)). 3 | - Your local machine needs to have `envsubst` and `kubectl` installed with access to that k8s cluster. 4 | - If you want to also deploy a working stripe exfiltration example, you will need a Stripe account and a test api key for that account (api keys starting with `sk_test`) 5 | 6 | Deployment Steps: 7 | - First choose a public endpoint outside of your cluster to fake data exfiltration to. This can be any HTTP endpoint that will accept POST requests. Once you have that endpoint run: 8 | ``` 9 | export EGRESS_URL=my-domain.tld/req/path 10 | ``` 11 | replacing `my-domain.tld` with the domain and `/req/path` with the path to the endpoint you're going to be using. 12 | - Now, if you have one, export your stripe test api key as an environment variable: 13 | ``` 14 | export STRIPE_TEST_API_KEY= 15 | ``` 16 | - [Deploy](https://docs.px.dev/installing-pixie/install-guides/community-cloud-for-pixie#4.-deploy-pixie) Pixie to your cluster. 17 | - Deploy the demo by running the following in the same terminal you ran the `export` commands: 18 | ``` 19 | kubectl create namespace px-data-exfiltration-demo 20 | envsubst < demo.yaml | kubectl apply -f - 21 | ``` 22 | - Explore the exfiltrated demo data in Pixie using the `px/cluster_egress` script. 23 | -------------------------------------------------------------------------------- /data-exfiltration-demo/demo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: malicious-pii-egress-https 6 | namespace: px-data-exfiltration-demo 7 | spec: 8 | containers: 9 | - name: malicious-pii-egress 10 | image: gcr.io/pixie-oss/pixie-dev/demo/data-exfiltration:latest 11 | env: 12 | - name: EGRESS_URL 13 | value: https://$EGRESS_URL 14 | --- 15 | apiVersion: v1 16 | kind: Pod 17 | metadata: 18 | name: malicious-pii-egress-http 19 | namespace: px-data-exfiltration-demo 20 | spec: 21 | containers: 22 | - name: malicious-pii-egress 23 | image: gcr.io/pixie-oss/pixie-dev/demo/data-exfiltration:latest 24 | env: 25 | - name: EGRESS_URL 26 | value: http://$EGRESS_URL 27 | --- 28 | apiVersion: v1 29 | kind: Pod 30 | metadata: 31 | name: legitimate-stripe-egress 32 | namespace: px-data-exfiltration-demo 33 | spec: 34 | containers: 35 | - name: legitimate-stripe-egress 36 | image: gcr.io/pixie-oss/pixie-dev/demo/data-exfiltration:latest 37 | env: 38 | - name: RUN_LEGITIMATE_EGRESS 39 | value: 'true' 40 | - name: STRIPE_TEST_API_KEY 41 | value: "$STRIPE_TEST_API_KEY" 42 | -------------------------------------------------------------------------------- /data-exfiltration-demo/go.mod: -------------------------------------------------------------------------------- 1 | module px.dev/data-exfiltration-demo 2 | 3 | go 1.17 4 | 5 | require github.com/stripe/stripe-go/v72 v72.104.0 6 | -------------------------------------------------------------------------------- /detect-monero-demo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.13 2 | 3 | RUN mkdir -p /app 4 | COPY ./xmrig /app 5 | COPY config.json /app 6 | RUN adduser -S -D -H -h /app/xmrig miner 7 | 8 | WORKDIR /app 9 | USER miner 10 | 11 | ENTRYPOINT ["/app/xmrig"] 12 | -------------------------------------------------------------------------------- /detect-monero-demo/detectrandomx.bt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018- The Pixie Authors. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | tracepoint:x86_fpu:x86_fpu_regs_deactivated 21 | { 22 | $f = (struct fpu *)args->fpu; 23 | $mxcsr = $f->state.xsave.i387.mxcsr; 24 | $fpcr = ($mxcsr & 0x6000) >> 13; 25 | if ($fpcr != 0) { 26 | printf("time_:%llu pid:%d comm:%s fpcr:%d\n", 27 | nsecs, pid, comm, $fpcr); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /detect-monero-demo/xmrig_deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: cryptocurrency 6 | --- 7 | apiVersion: apps/v1 8 | kind: Deployment 9 | metadata: 10 | name: xmrig-deployment 11 | namespace: cryptocurrency 12 | labels: 13 | app: xmrig 14 | spec: 15 | replicas: 1 16 | selector: 17 | matchLabels: 18 | app: xmrig 19 | template: 20 | metadata: 21 | labels: 22 | app: xmrig 23 | spec: 24 | containers: 25 | - name: xmrig 26 | image: xmrig:latest 27 | imagePullPolicy: Never 28 | ports: 29 | - containerPort: 80 30 | -------------------------------------------------------------------------------- /ebpf-profiler/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018- The Pixie Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # SPDX-License-Identifier: Apache-2.0 17 | 18 | all: perf_profiler sqrt 19 | 20 | perf_profiler: perf_profiler.cc 21 | clang++ --std=c++17 -o $@ $^ -lbcc 22 | 23 | sqrt: toy_app/sqrt.go 24 | go build $^ 25 | 26 | clean: 27 | rm perf_profiler sqrt 28 | -------------------------------------------------------------------------------- /ebpf-profiler/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Performance Profiler using eBPF 3 | 4 | This is a demo performance profiler, written to accompany the Pixie [blog post](https://blog.px.dev/cpu-profiling). 5 | It shows how to get sample stack traces for performance profiling, using eBPF. 6 | 7 | ## Prerequisites 8 | 9 | You must have the BCC development package installed. On Ubuntu, the package can be installed as follows: 10 | 11 | ``` 12 | sudo apt install libbpfcc-dev 13 | ``` 14 | 15 | Other distributions have similar commands. 16 | 17 | ## Build 18 | 19 | To compile, execute the following command: 20 | 21 | ``` 22 | make 23 | ``` 24 | 25 | ## Run Demo Application 26 | 27 | A demo application to profile is included: `toy_app/sqrt.go` 28 | 29 | ## Run Tracer 30 | 31 | The BPF performance profiler is run as follows: 32 | 33 | ``` 34 | sudo ./perf_profiler 35 | ``` 36 | 37 | To run it on the demo app for 30 seconds, run the following command in a separate terminal: 38 | ``` 39 | sudo ./perf_profiler $(pgrep -f "sqrt") 30 40 | ``` 41 | 42 | -------------------------------------------------------------------------------- /ebpf-profiler/perf_profiler_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018- The Pixie Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * SPDX-License-Identifier: Apache-2.0 17 | */ 18 | 19 | #pragma once 20 | 21 | struct stack_trace_key_t { 22 | pid_t pid; 23 | 24 | // user_stack_id, an index into the stack-traces map. 25 | int user_stack_id; 26 | 27 | // kernel_stack_id, an index into the stack-traces map. 28 | int kernel_stack_id; 29 | }; 30 | -------------------------------------------------------------------------------- /eks-workshop/README.md: -------------------------------------------------------------------------------- 1 | Resources used in the ["Monitoring with Pixie"](https://www.eksworkshop.com/intermediate/241_pixie/) AWS EKS Workshop. 2 | 3 | If you have any questions, please reach out on our [Pixie Community Slack](https://slackin.px.dev/) or file a GitHub issue. 4 | -------------------------------------------------------------------------------- /eks-workshop/clusterconfig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: eksctl.io/v1alpha5 3 | kind: ClusterConfig 4 | 5 | metadata: 6 | name: eksworkshop-eksctl 7 | region: ${AWS_REGION} 8 | 9 | # https://eksctl.io/usage/eks-managed-nodegroups/ 10 | managedNodeGroups: 11 | - name: pixie-demo-ng 12 | minSize: 2 13 | maxSize: 3 14 | desiredCapacity: 3 15 | volumeSize: 20 16 | labels: {role: ctrl-workers} 17 | tags: 18 | nodegroup-role: ctrl-workers 19 | iam: 20 | withAddonPolicies: 21 | appMesh: true 22 | xRay: true 23 | cloudWatch: true 24 | 25 | # https://eksctl.io/usage/iamserviceaccounts/ 26 | iam: 27 | withOIDC: true 28 | serviceAccounts: 29 | - metadata: 30 | name: pixie-demo-sa 31 | namespace: pixie-demo-ns 32 | labels: {aws-usage: "application"} 33 | attachPolicyARNs: 34 | - "arn:aws:iam::aws:policy/AWSAppMeshEnvoyAccess" 35 | - "arn:aws:iam::aws:policy/AWSCloudMapDiscoverInstanceAccess" 36 | - "arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess" 37 | - "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess" 38 | - "arn:aws:iam::aws:policy/AWSAppMeshFullAccess" 39 | - "arn:aws:iam::aws:policy/AWSCloudMapFullAccess" 40 | -------------------------------------------------------------------------------- /endpoint-deprecation/.readme_assets/service_endpoint_requests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/endpoint-deprecation/.readme_assets/service_endpoint_requests.png -------------------------------------------------------------------------------- /endpoint-deprecation/.readme_assets/service_endpoints_summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/endpoint-deprecation/.readme_assets/service_endpoints_summary.png -------------------------------------------------------------------------------- /endpoint-deprecation/.readme_assets/unique_req_header_values.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/endpoint-deprecation/.readme_assets/unique_req_header_values.png -------------------------------------------------------------------------------- /endpoint-deprecation/demo-app.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: echo-service 6 | labels: 7 | name: echo-service 8 | namespace: default 9 | spec: 10 | selector: 11 | matchLabels: 12 | name: echo-service 13 | template: 14 | metadata: 15 | labels: 16 | name: echo-service 17 | plane: control 18 | spec: 19 | containers: 20 | - name: app 21 | image: gcr.io/pixie-oss/pixie-dev/demo/http_echo_image:latest 22 | ports: 23 | - containerPort: 8080 24 | --- 25 | apiVersion: v1 26 | kind: Service 27 | metadata: 28 | name: echo-service 29 | labels: 30 | name: echo-service 31 | namespace: default 32 | spec: 33 | type: LoadBalancer 34 | ports: 35 | - port: 80 36 | targetPort: 8080 37 | selector: 38 | name: echo-service 39 | -------------------------------------------------------------------------------- /endpoint-deprecation/service_endpoint_requests/manifest.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | short: Service Endpoints Requests 3 | long: > 4 | This script shows requests made to a service endpoint. 5 | -------------------------------------------------------------------------------- /endpoint-deprecation/service_endpoint_requests/vis.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": [ 3 | { 4 | "name": "start_time", 5 | "type": "PX_STRING", 6 | "description": "The relative start time of the window. Current time is assumed to be now", 7 | "defaultValue": "-5m" 8 | }, 9 | { 10 | "name": "service", 11 | "type": "PX_SERVICE", 12 | "description": "The name of the service to get stats for. Format: namespace/svc_name" 13 | }, 14 | { 15 | "name": "endpoint", 16 | "type": "PX_STRING", 17 | "description": "The endpoint to look at stats for. Format: /path/to/endpoint/*/more/path ", 18 | "defaultValue": "" 19 | } 20 | ], 21 | "globalFuncs": [], 22 | "widgets": [ 23 | { 24 | "name": "Endpoint Requests", 25 | "position": { 26 | "x": 0, 27 | "y": 0, 28 | "w": 12, 29 | "h": 3 30 | }, 31 | "func": { 32 | "name": "endpoints", 33 | "args": [ 34 | { 35 | "name": "start_time", 36 | "variable": "start_time" 37 | }, 38 | { 39 | "name": "service", 40 | "variable": "service" 41 | }, 42 | { 43 | "name": "endpoint", 44 | "variable": "endpoint" 45 | } 46 | ] 47 | }, 48 | "displaySpec": { 49 | "@type": "types.px.dev/px.vispb.Table" 50 | } 51 | } 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /endpoint-deprecation/service_endpoints_summary/manifest.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | short: Service Endpoints Summary 3 | long: > 4 | This script gets an overview of the endpoints for a service, summarizing their request statistics. 5 | -------------------------------------------------------------------------------- /endpoint-deprecation/service_endpoints_summary/vis.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": [ 3 | { 4 | "name": "start_time", 5 | "type": "PX_STRING", 6 | "description": "The relative start time of the window. Current time is assumed to be now", 7 | "defaultValue": "-5m" 8 | }, 9 | { 10 | "name": "service", 11 | "type": "PX_SERVICE", 12 | "description": "The name of the service to get stats for. Format: namespace/svc_name" 13 | } 14 | ], 15 | "globalFuncs": [], 16 | "widgets": [ 17 | { 18 | "name": "Service Endpoints", 19 | "position": { 20 | "x": 0, 21 | "y": 0, 22 | "w": 4, 23 | "h": 3 24 | }, 25 | "func": { 26 | "name": "endpoints", 27 | "args": [ 28 | { 29 | "name": "start_time", 30 | "variable": "start_time" 31 | }, 32 | { 33 | "name": "service", 34 | "variable": "service" 35 | } 36 | ] 37 | }, 38 | "displaySpec": { 39 | "@type": "types.px.dev/px.vispb.Table" 40 | } 41 | } 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /endpoint-deprecation/service_requests/manifest.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | short: Service Requests 3 | long: > 4 | This script requests made to the specified service. 5 | -------------------------------------------------------------------------------- /endpoint-deprecation/service_requests/vis.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": [ 3 | { 4 | "name": "start_time", 5 | "type": "PX_STRING", 6 | "description": "The relative start time of the window. Current time is assumed to be now", 7 | "defaultValue": "-5m" 8 | }, 9 | { 10 | "name": "service", 11 | "type": "PX_SERVICE", 12 | "description": "The name of the service to get stats for. Format: namespace/svc_name" 13 | } 14 | ], 15 | "globalFuncs": [], 16 | "widgets": [ 17 | { 18 | "name": "Serivce Requests", 19 | "position": { 20 | "x": 0, 21 | "y": 0, 22 | "w": 12, 23 | "h": 3 24 | }, 25 | "func": { 26 | "name": "endpoints", 27 | "args": [ 28 | { 29 | "name": "start_time", 30 | "variable": "start_time" 31 | }, 32 | { 33 | "name": "service", 34 | "variable": "service" 35 | } 36 | ] 37 | }, 38 | "displaySpec": { 39 | "@type": "types.px.dev/px.vispb.Table" 40 | } 41 | } 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /endpoint-deprecation/unique_req_header_values/manifest.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | short: Endpoints Request Header Values 3 | long: > 4 | This script shows a list of unique request header field values. 5 | -------------------------------------------------------------------------------- /endpoint-deprecation/unique_req_header_values/vis.json: -------------------------------------------------------------------------------- 1 | { 2 | "variables": [ 3 | { 4 | "name": "start_time", 5 | "type": "PX_STRING", 6 | "description": "The relative start time of the window. Current time is assumed to be now", 7 | "defaultValue": "-5m" 8 | }, 9 | { 10 | "name": "service", 11 | "type": "PX_SERVICE", 12 | "description": "The name of the service to get stats for. Format: namespace/svc_name" 13 | }, 14 | { 15 | "name": "endpoint", 16 | "type": "PX_STRING", 17 | "description": "The endpoint to look at stats for. Format: /path/to/endpoint/*/more/path " 18 | } 19 | ], 20 | "globalFuncs": [], 21 | "widgets": [ 22 | { 23 | "name": "Endpoint Request Headers", 24 | "position": { 25 | "x": 0, 26 | "y": 0, 27 | "w": 12, 28 | "h": 3 29 | }, 30 | "func": { 31 | "name": "endpoints", 32 | "args": [ 33 | { 34 | "name": "start_time", 35 | "variable": "start_time" 36 | }, 37 | { 38 | "name": "service", 39 | "variable": "service" 40 | }, 41 | { 42 | "name": "endpoint", 43 | "variable": "endpoint" 44 | } 45 | ] 46 | }, 47 | "displaySpec": { 48 | "@type": "types.px.dev/px.vispb.Table" 49 | } 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /go-garbage-collector/.readme_assets/gc_events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/go-garbage-collector/.readme_assets/gc_events.png -------------------------------------------------------------------------------- /go-garbage-collector/.readme_assets/sweep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/go-garbage-collector/.readme_assets/sweep.png -------------------------------------------------------------------------------- /go-garbage-collector/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM golang:1.16-alpine 4 | 5 | WORKDIR /app 6 | 7 | COPY go.mod ./ 8 | RUN go mod download 9 | 10 | COPY *.go ./ 11 | 12 | RUN go build -o /simple-server 13 | 14 | EXPOSE 8080 15 | 16 | CMD ["/simple-server", "--logtostderr=true"] 17 | -------------------------------------------------------------------------------- /go-garbage-collector/demo-app.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: gc-service 6 | labels: 7 | name: gc-service 8 | namespace: default 9 | spec: 10 | selector: 11 | matchLabels: 12 | name: gc-service 13 | template: 14 | metadata: 15 | labels: 16 | name: gc-service 17 | plane: control 18 | spec: 19 | containers: 20 | - name: app 21 | image: gcr.io/pixie-oss/pixie-dev/demo/go_garbage_collection_image:latest 22 | ports: 23 | - containerPort: 8080 24 | --- 25 | apiVersion: v1 26 | kind: Service 27 | metadata: 28 | name: gc-service 29 | labels: 30 | name: gc-service 31 | namespace: default 32 | spec: 33 | type: LoadBalancer 34 | ports: 35 | - port: 80 36 | targetPort: 8080 37 | selector: 38 | name: gc-service 39 | -------------------------------------------------------------------------------- /go-garbage-collector/go.mod: -------------------------------------------------------------------------------- 1 | module px.dev/example-gc-server 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/GC.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | GCTable = 'GC' 23 | 24 | # Probe for GC in Go v1.16. 25 | # https://github.com/golang/go/blob/go1.16/src/runtime/mgc.go#L1126 26 | def GC(): 27 | table_name = GCTable 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("runtime.GC") 31 | def probe_func(): 32 | return [{'latency': pxtrace.FunctionLatency()}] 33 | 34 | 35 | pxtrace.UpsertTracepoint(tp_name, 36 | table_name, 37 | probe_func, 38 | pxtrace.PodProcess(pod), 39 | "12h") 40 | 41 | df = px.DataFrame(table_name, start_time="-1m") 42 | return df 43 | 44 | 45 | px.display(GC()) 46 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/_canary_probe.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | canaryTable = 'canary' 23 | 24 | # Canary probe to test that you can successfully deploy Go probes 25 | # before moving onto the main probes. 26 | def canaryProbe(): 27 | table_name = canaryTable 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("generateRandomString") 31 | def probe_func(): 32 | return [ 33 | {'n': pxtrace.ArgExpr('n')}, 34 | {'latency': pxtrace.FunctionLatency()}] 35 | 36 | pxtrace.UpsertTracepoint(tp_name, 37 | table_name, 38 | probe_func, 39 | pxtrace.PodProcess(pod), 40 | "1m") 41 | 42 | df = px.DataFrame(table_name, start_time="-1m") 43 | return df 44 | 45 | 46 | px.display(canaryProbe()) 47 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/allocSpan.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | allocSpanTable = 'allocSpan' 23 | 24 | # Probe for allocSpan in Go v1.16. 25 | # https://github.com/golang/go/blob/go1.16/src/runtime/mheap.go#L1124 26 | def allocSpan(): 27 | table_name = allocSpanTable 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("(*mheap).allocSpan") 31 | def probe_func(): 32 | return [ 33 | {'npages': pxtrace.ArgExpr('npages')}, 34 | {'latency': pxtrace.FunctionLatency()}] 35 | 36 | pxtrace.UpsertTracepoint(tp_name, 37 | table_name, 38 | probe_func, 39 | pxtrace.PodProcess(pod), 40 | "12h") 41 | 42 | df = px.DataFrame(table_name, start_time="-1m") 43 | return df 44 | 45 | 46 | px.display(allocSpan()) 47 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/gcAssistAlloc1.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | gcAssistAlloc1Table = 'gcAssistAlloc1' 23 | 24 | # Probe for gcAssistAlloc1 in Go v1.16. 25 | # https://github.com/golang/go/blob/go1.16/src/runtime/mgcmark.go#L504 26 | def gcAssistAlloc1(): 27 | table_name = gcAssistAlloc1Table 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("runtime.gcAssistAlloc1") 31 | def probe_func(): 32 | return [ 33 | {'scanWork': pxtrace.ArgExpr('scanWork')}, 34 | {'latency': pxtrace.FunctionLatency()}] 35 | 36 | pxtrace.UpsertTracepoint(tp_name, 37 | table_name, 38 | probe_func, 39 | pxtrace.PodProcess(pod), 40 | "12h") 41 | 42 | df = px.DataFrame(table_name, start_time="-1m") 43 | return df 44 | 45 | 46 | px.display(gcAssistAlloc1()) 47 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/gcSweep.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | gcSweepTable = 'gcSweep' 23 | 24 | # Probe for gcSweep in Go v1.16. 25 | # https://github.com/golang/go/blob/go1.16/src/runtime/mgc.go#L2170 26 | def gcSweep(): 27 | table_name = gcSweepTable 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("runtime.gcSweep") 31 | def probe_func(): 32 | return [{'latency': pxtrace.FunctionLatency()}] 33 | 34 | 35 | pxtrace.UpsertTracepoint(tp_name, 36 | table_name, 37 | probe_func, 38 | pxtrace.PodProcess(pod), 39 | "12h") 40 | 41 | df = px.DataFrame(table_name, start_time="-1m") 42 | return df 43 | 44 | 45 | px.display(gcSweep()) 46 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/gcWaitOnMark.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | gcWaitOnMarkTable = 'gcWaitOnMark' 23 | 24 | # Probe for gcWaitOnMark in Go v1.16. 25 | # https://github.com/golang/go/blob/go1.16/src/runtime/mgc.go#L1201 26 | def gcWaitOnMark(): 27 | table_name = gcWaitOnMarkTable 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("gcWaitOnMark") 31 | def probe_func(): 32 | return [ 33 | {'n': pxtrace.ArgExpr('n')}, 34 | {'latency': pxtrace.FunctionLatency()} 35 | ] 36 | 37 | 38 | pxtrace.UpsertTracepoint(tp_name, 39 | table_name, 40 | probe_func, 41 | pxtrace.PodProcess(pod), 42 | "12h") 43 | 44 | df = px.DataFrame(table_name, start_time="-1m") 45 | return df 46 | 47 | px.display(gcWaitOnMark()) 48 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/startTheWorldWithSema.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | startTheWorldWithSemaTable = 'startTheWorldWithSema' 23 | 24 | # Probe for startTheWorldWithSema in Go v1.16. 25 | # https://github.com/golang/go/blob/go1.16/src/runtime/proc.go#L1151 26 | def startTheWorldWithSema(): 27 | table_name = startTheWorldWithSemaTable 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("startTheWorldWithSema") 31 | def probe_func(): 32 | return [ 33 | {'latency': pxtrace.FunctionLatency()} 34 | ] 35 | 36 | 37 | pxtrace.UpsertTracepoint(tp_name, 38 | table_name, 39 | probe_func, 40 | pxtrace.PodProcess(pod), 41 | "12h") 42 | 43 | df = px.DataFrame(table_name, start_time="-1m") 44 | return df 45 | 46 | px.display(startTheWorldWithSema()) 47 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/stopTheWorldWithSema.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | stopTheWorldWithSemaTable = 'stopTheWorldWithSema' 23 | 24 | # Probe for stopTheWorldWithSema in Go v1.16. 25 | # https://github.com/golang/go/blob/go1.16/src/runtime/proc.go#L1073 26 | def stopTheWorldWithSema(): 27 | table_name = stopTheWorldWithSemaTable 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("stopTheWorldWithSema") 31 | def probe_func(): 32 | return [ 33 | {'latency': pxtrace.FunctionLatency()} 34 | ] 35 | 36 | 37 | pxtrace.UpsertTracepoint(tp_name, 38 | table_name, 39 | probe_func, 40 | pxtrace.PodProcess(pod), 41 | "12h") 42 | 43 | df = px.DataFrame(table_name, start_time="-1m") 44 | return df 45 | 46 | px.display(stopTheWorldWithSema()) 47 | -------------------------------------------------------------------------------- /go-garbage-collector/pxl_scripts/uprobe_scripts/sweepone.pxl: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | import px 18 | import pxtrace 19 | 20 | # Pod names should be written in / format, e.g. `default/pod-123`. 21 | pod = '' 22 | sweeponeTable = 'sweepone' 23 | 24 | # Probe for sweepone in Go v1.16. 25 | # https://github.com/golang/go/blob/go1.16/src/runtime/mgcsweep.go#L188 26 | def sweepone(): 27 | table_name = sweeponeTable 28 | tp_name = table_name 29 | 30 | @pxtrace.probe("sweepone") 31 | def probe_func(): 32 | return [ 33 | {'npages': pxtrace.RetExpr('$0')}, 34 | {'latency': pxtrace.FunctionLatency()}] 35 | 36 | 37 | pxtrace.UpsertTracepoint(tp_name, 38 | table_name, 39 | probe_func, 40 | pxtrace.PodProcess(pod), 41 | "12h") 42 | 43 | df = px.DataFrame(table_name, start_time="-1m") 44 | return df 45 | 46 | px.display(sweepone()) 47 | -------------------------------------------------------------------------------- /http2-tracing/.readme_assets/http2_header_lookup_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/http2-tracing/.readme_assets/http2_header_lookup_table.png -------------------------------------------------------------------------------- /http2-tracing/.readme_assets/uprobe_tracer_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/http2-tracing/.readme_assets/uprobe_tracer_output.png -------------------------------------------------------------------------------- /http2-tracing/.readme_assets/wireshark_http2_headers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/http2-tracing/.readme_assets/wireshark_http2_headers.png -------------------------------------------------------------------------------- /http2-tracing/.readme_assets/wireshark_http2_headers_failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/http2-tracing/.readme_assets/wireshark_http2_headers_failed.png -------------------------------------------------------------------------------- /http2-tracing/.readme_assets/wireshark_http2_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/http2-tracing/.readme_assets/wireshark_http2_setting.png -------------------------------------------------------------------------------- /http2-tracing/.readme_assets/wireshark_packets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/http2-tracing/.readme_assets/wireshark_packets.png -------------------------------------------------------------------------------- /http2-tracing/go.mod: -------------------------------------------------------------------------------- 1 | module pixielabs.ai/pixie/demos/http2-tracing 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/fatih/color v1.13.0 // indirect 7 | github.com/iovisor/gobpf v0.0.0-20200614202714-e6b321d32103 8 | // Use one of the below to replace the above gobpf version if needed. 9 | // See README.md for details. 10 | // github.com/iovisor/gobpf v0.1.0 // indirect 11 | // github.com/iovisor/gobpf v0.2.0 // indirect 12 | golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect 13 | google.golang.org/grpc v1.43.0 // indirect 14 | google.golang.org/protobuf v1.25.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /http2-tracing/proto/greet.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018- The Pixie Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * SPDX-License-Identifier: Apache-2.0 17 | */ 18 | 19 | syntax = "proto3"; 20 | 21 | package greet; 22 | 23 | option go_package = "proto/greetpb;greetpb"; 24 | 25 | // The greeting service. Used to demo HTTP2 tracer with gRPC application. 26 | service Greeter { 27 | // Sends a greeting to the provided name. 28 | rpc SayHello(HelloRequest) returns (HelloReply); 29 | } 30 | 31 | // The request message containing the name to greet. 32 | message HelloRequest { 33 | string name = 1; 34 | } 35 | 36 | // The response message containing the greeting to a name. 37 | message HelloReply { 38 | string message = 1; 39 | } 40 | -------------------------------------------------------------------------------- /http2-tracing/server/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018- The Pixie Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * SPDX-License-Identifier: Apache-2.0 17 | */ 18 | 19 | package main 20 | 21 | import ( 22 | "context" 23 | "flag" 24 | "log" 25 | "net" 26 | "strconv" 27 | 28 | "google.golang.org/grpc" 29 | 30 | pb "pixielabs.ai/pixie/demos/http2-tracing/proto/greetpb" 31 | ) 32 | 33 | type server struct{} 34 | 35 | func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { 36 | return &pb.HelloReply{Message: "Hello " + in.Name}, nil 37 | } 38 | 39 | func main() { 40 | port := flag.Int("port", 50051, "The port to listen.") 41 | flag.Parse() 42 | 43 | log.Printf("Starting http server on port: %d", *port) 44 | lis, err := net.Listen("tcp", ":"+strconv.Itoa(*port)) 45 | if err != nil { 46 | log.Fatalf("failed to listen: %v", err) 47 | } 48 | 49 | s := grpc.NewServer() 50 | 51 | log.Printf("Launching unary server") 52 | pb.RegisterGreeterServer(s, &server{}) 53 | 54 | if err := s.Serve(lis); err != nil { 55 | log.Fatalf("failed to serve: %v", err) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pixie Demos 5 | 6 | 28 | 29 | 30 |
31 |

Pixie Demos

32 |

This page serves to host web app demos for Pixie.

33 |

Check the links below to visit each demo.

34 | 41 |
42 | 43 | -------------------------------------------------------------------------------- /k8s-cost-estimation/.readme_assets/cost_per_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/k8s-cost-estimation/.readme_assets/cost_per_request.png -------------------------------------------------------------------------------- /k8s-cost-estimation/mem_cost.pxl: -------------------------------------------------------------------------------- 1 | import px 2 | 3 | bytes_per_gb = 1024 * 1024 * 1024 4 | 5 | # Adjust this value based on your cloud provider's pricing. 6 | mem_gb_cost_per_hour = 0.004 7 | 8 | 9 | def hourly_mem_by_service(): 10 | # Load the last 1 hr of Pixie's 'process_stats' table into a Dataframe. 11 | # The 'process_stats' table contains CPU, memory and IO stats for all 12 | # K8s processes in your cluster. 13 | df = px.DataFrame(table='process_stats', start_time="-1h") 14 | 15 | # Add K8s context using the table record's UPID. 16 | df.service = df.ctx['service'] 17 | 18 | # Calculate memory usage for each process (UPID) in each service. 19 | df = df.groupby(['service', 'upid']).agg( 20 | rss=('rss_bytes', px.mean) 21 | ) 22 | 23 | # Sum memory time by service. 24 | df = df.groupby('service').agg( 25 | rss_bytes=('rss', px.sum) 26 | ) 27 | df.rss_gb = df.rss_bytes / bytes_per_gb 28 | return df 29 | 30 | 31 | def yearly_mem_cost_by_service(): 32 | df = hourly_mem_by_service() 33 | # Estimate yearly usage based on last hour of usage. 34 | df.mem_cost_per_year = df.rss_gb * mem_gb_cost_per_hour * 24 * 365 35 | return df[['service', 'mem_cost_per_year']] 36 | 37 | 38 | def yearly_mem_cost(): 39 | df = yearly_mem_cost_by_service() 40 | # Calcualte yearly CPU cost across all services. 41 | return df.agg( 42 | mem_cost_per_year=('mem_cost_per_year', px.sum) 43 | ) 44 | 45 | 46 | df = yearly_mem_cost_by_service() 47 | px.display(df, 'Estimated Memory Cost By Service (Yearly)') 48 | 49 | df = yearly_mem_cost() 50 | px.display(df, 'Estimated Memory Cost (Yearly)') 51 | -------------------------------------------------------------------------------- /openssl-tracer/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2018- The Pixie Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # SPDX-License-Identifier: Apache-2.0 16 | 17 | openssl_tracer: openssl_tracer.cc probe_deployment.cc 18 | clang++ --std=c++17 -o $@ $^ -lbcc 19 | 20 | clean: 21 | rm openssl_tracer 22 | -------------------------------------------------------------------------------- /openssl-tracer/README.md: -------------------------------------------------------------------------------- 1 | # OpenSSL Tracer using BPF 2 | 3 | This is a basic example of how to trace the OpenSSL library using eBPF. 4 | This tracer uses BCC to deploy the eBPF probes. 5 | This demo was created to accompany the "Debugging with eBPF Part 3: Tracing SSL/TLS connections" [blog post](https://blog.px.dev/ebpf-openssl-tracing/). 6 | 7 | ## Prerequisites 8 | 9 | You must have the BCC development package installed. On Ubuntu, the package can be installed as follows: 10 | 11 | ``` 12 | sudo apt install libbpfcc-dev 13 | ``` 14 | 15 | Other distributions have similar commands. 16 | 17 | ## Build 18 | 19 | To compile, execute the following command: 20 | 21 | ``` 22 | make 23 | ``` 24 | 25 | ## Run Demo Application 26 | 27 | A demo application to trace is included. It is a simple client-server written in Python, which uses OpenSSL. 28 | 29 | First, you'll have to generate some certificates for the client and server. 30 | To keep things simple, you can generate some self-signed certificates as follows: 31 | 32 | ``` 33 | make -C ssl_client_server certs 34 | ``` 35 | 36 | To run the demo app, you'll need two terminals. 37 | 38 | In one terminal, run the server: 39 | 40 | ``` 41 | cd ssl_client_server; ./server.py 42 | ``` 43 | 44 | In the second terminal, run the client: 45 | 46 | ``` 47 | cd ssl_client_server; ./client.py 48 | ``` 49 | 50 | ## Run Tracer 51 | 52 | The BPF tracer is run as follows: 53 | 54 | ``` 55 | sudo ./openssl_tracer 56 | ``` 57 | 58 | To run it on the demo app, run the following command in a separate terminal: 59 | 60 | ``` 61 | sudo ./openssl_tracer $(pgrep -f "./client.py") 62 | ``` 63 | -------------------------------------------------------------------------------- /openssl-tracer/openssl_tracer_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018- The Pixie Authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | * SPDX-License-Identifier: Apache-2.0 17 | */ 18 | 19 | #pragma once 20 | 21 | #define MAX_DATA_SIZE 4096 22 | 23 | enum ssl_data_event_type { kSSLRead, kSSLWrite }; 24 | 25 | struct ssl_data_event_t { 26 | enum ssl_data_event_type type; 27 | uint64_t timestamp_ns; 28 | uint32_t pid; 29 | uint32_t tid; 30 | char data[MAX_DATA_SIZE]; 31 | int32_t data_len; 32 | }; 33 | -------------------------------------------------------------------------------- /openssl-tracer/ssl_client_server/Makefile: -------------------------------------------------------------------------------- 1 | 2 | certs: 3 | openssl req -x509 -nodes -newkey rsa:4096 -keyout client.key -out client.crt -days 365 -subj '/CN=example.com' 4 | openssl req -x509 -nodes -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -subj '/CN=example.com' 5 | 6 | clean: 7 | rm -f client.key client.crt 8 | rm -f server.key server.crt 9 | 10 | -------------------------------------------------------------------------------- /openssl-tracer/ssl_client_server/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2018- The Pixie Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # SPDX-License-Identifier: Apache-2.0 18 | 19 | import socket 20 | import ssl 21 | import time 22 | import random 23 | 24 | host_addr = '127.0.0.1' 25 | host_port = 8082 26 | 27 | server_sni_hostname = 'example.com' 28 | client_cert = 'client.crt' 29 | client_key = 'client.key' 30 | server_cert = 'server.crt' 31 | 32 | context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=server_cert) 33 | context.load_cert_chain(certfile=client_cert, keyfile=client_key) 34 | 35 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 36 | conn = context.wrap_socket(s, server_side=False, server_hostname=server_sni_hostname) 37 | conn.connect((host_addr, host_port)) 38 | print("SSL established.") 39 | 40 | count = 0 41 | while True: 42 | time.sleep(1) 43 | secret = random.randint(0, 1024 * 1024 * 1024) 44 | conn.send("Client secret {} is {}".format(count, secret).encode()) 45 | data = conn.recv(1024) 46 | print(data.decode()) 47 | count += 1 48 | 49 | print("Closing connection") 50 | conn.close() 51 | -------------------------------------------------------------------------------- /react-table/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/.nojekyll -------------------------------------------------------------------------------- /react-table/1-basics/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # Allowed because it's being hosted as a GitHub page. 13 | # Wonky, but it works in a pinch. 14 | # /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /react-table/1-basics/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Basic Demo 2 | 3 | Demo for the first step in [this tutorial](https://blog.px.dev/tables-are-hard-2). 4 | 5 | [Back to Top](../README.md) 6 | 7 | How this was created: 8 | * Install NodeJS version 14 or above 9 | * `npx create-react-app 1-basics --use-npm` 10 | * `cd 1-basics` 11 | * `npm start` 12 | * Added `Table.js`, `Table.module.css`, and `utils/makeData.js` 13 | * Replaced the default Create React App component with a basic table using `makeData.js`. 14 | * Removed `src/logo.svg` since we're not using it. -------------------------------------------------------------------------------- /react-table/1-basics/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/pixie-demos/react-table/1-basics/build/static/css/main.5b9e8232.chunk.css", 4 | "main.js": "/pixie-demos/react-table/1-basics/build/static/js/main.fd5d59cd.chunk.js", 5 | "main.js.map": "/pixie-demos/react-table/1-basics/build/static/js/main.fd5d59cd.chunk.js.map", 6 | "runtime-main.js": "/pixie-demos/react-table/1-basics/build/static/js/runtime-main.3b1ab93e.js", 7 | "runtime-main.js.map": "/pixie-demos/react-table/1-basics/build/static/js/runtime-main.3b1ab93e.js.map", 8 | "static/js/2.9033903f.chunk.js": "/pixie-demos/react-table/1-basics/build/static/js/2.9033903f.chunk.js", 9 | "static/js/2.9033903f.chunk.js.map": "/pixie-demos/react-table/1-basics/build/static/js/2.9033903f.chunk.js.map", 10 | "static/js/3.ab8d20b9.chunk.js": "/pixie-demos/react-table/1-basics/build/static/js/3.ab8d20b9.chunk.js", 11 | "static/js/3.ab8d20b9.chunk.js.map": "/pixie-demos/react-table/1-basics/build/static/js/3.ab8d20b9.chunk.js.map", 12 | "index.html": "/pixie-demos/react-table/1-basics/build/index.html", 13 | "static/css/main.5b9e8232.chunk.css.map": "/pixie-demos/react-table/1-basics/build/static/css/main.5b9e8232.chunk.css.map", 14 | "static/js/2.9033903f.chunk.js.LICENSE.txt": "/pixie-demos/react-table/1-basics/build/static/js/2.9033903f.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.3b1ab93e.js", 18 | "static/js/2.9033903f.chunk.js", 19 | "static/css/main.5b9e8232.chunk.css", 20 | "static/js/main.fd5d59cd.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /react-table/1-basics/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/1-basics/build/favicon.ico -------------------------------------------------------------------------------- /react-table/1-basics/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/1-basics/build/logo192.png -------------------------------------------------------------------------------- /react-table/1-basics/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/1-basics/build/logo512.png -------------------------------------------------------------------------------- /react-table/1-basics/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/1-basics/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/1-basics/build/static/css/main.5b9e8232.chunk.css: -------------------------------------------------------------------------------- 1 | body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.Table_Table__gTzsf{font-size:1rem;text-align:left;border-collapse:collapse;width:100%}.Table_Table__gTzsf td,.Table_Table__gTzsf th{line-height:2em;padding:0 .75em;border:1px solid hsla(0,0%,100%,.75)}.Table_Table__gTzsf th{padding:.75em;border-bottom-width:2px}body{background-color:#282c34;font-size:calc(10px + 2vmin);color:#fff}.App{width:100vw;height:100%;min-height:100vh;display:flex;flex-flow:column nowrap;justify-content:center;align-items:center}a{color:#61dafb}main{padding:2rem;text-align:center;box-sizing:border-box;width:100%} 2 | /*# sourceMappingURL=main.5b9e8232.chunk.css.map */ -------------------------------------------------------------------------------- /react-table/1-basics/build/static/css/main.5b9e8232.chunk.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://src/index.css","webpack://src/Table.module.css","webpack://src/App.css"],"names":[],"mappings":"AAAA,KACE,QAAS,CACT,mJAEY,CACZ,kCAAmC,CACnC,iCACF,CAEA,KACE,yEAEF,CCZA,oBACE,cAAe,CACf,eAAgB,CAChB,wBAAyB,CACzB,UACF,CAEA,8CACE,eAAgB,CAChB,eAAiB,CACjB,oCACF,CAEA,uBACE,aAAsB,CACtB,uBACF,CChBA,KAEE,wBAAyB,CACzB,4BAA6B,CAC7B,UACF,CAEA,KAEE,WAAY,CACZ,WAAY,CACZ,gBAAiB,CACjB,YAAa,CACb,uBAAwB,CACxB,sBAAuB,CACvB,kBACF,CAEA,EACE,aACF,CAEA,KACE,YAAa,CACb,iBAAkB,CAClB,qBAAsB,CACtB,UACF","file":"main.5b9e8232.chunk.css","sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n",".Table {\n font-size: 1rem;\n text-align: left;\n border-collapse: collapse;\n width: 100%;\n}\n\n.Table td, .Table th {\n line-height: 2em;\n padding: 0 0.75em;\n border: 1px rgba(255, 255, 255, 0.75) solid;\n}\n\n.Table th {\n padding: 0.75em 0.75em;\n border-bottom-width: 2px;\n}","body {\n /* Make it look nice */\n background-color: #282c34;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App {\n /* Super basic container to fill the page and center contents */\n width: 100vw;\n height: 100%;\n min-height: 100vh;\n display: flex;\n flex-flow: column nowrap;\n justify-content: center;\n align-items: center;\n}\n\na {\n color: #61dafb;\n}\n\nmain {\n padding: 2rem;\n text-align: center;\n box-sizing: border-box;\n width: 100%;\n}\n"]} -------------------------------------------------------------------------------- /react-table/1-basics/build/static/js/2.9033903f.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.20.2 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v17.0.2 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v17.0.2 26 | * react-jsx-runtime.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | 34 | /** @license React v17.0.2 35 | * react.production.min.js 36 | * 37 | * Copyright (c) Facebook, Inc. and its affiliates. 38 | * 39 | * This source code is licensed under the MIT license found in the 40 | * LICENSE file in the root directory of this source tree. 41 | */ 42 | -------------------------------------------------------------------------------- /react-table/1-basics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-table-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/pixie-demos/react-table/1-basics/build", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.16.1", 8 | "@testing-library/react": "^11.2.7", 9 | "@testing-library/user-event": "^12.8.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "web-vitals": "^1.1.2" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /react-table/1-basics/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/1-basics/public/favicon.ico -------------------------------------------------------------------------------- /react-table/1-basics/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/1-basics/public/logo192.png -------------------------------------------------------------------------------- /react-table/1-basics/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/1-basics/public/logo512.png -------------------------------------------------------------------------------- /react-table/1-basics/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/1-basics/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/1-basics/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* Make it look nice */ 3 | background-color: #282c34; 4 | font-size: calc(10px + 2vmin); 5 | color: white; 6 | } 7 | 8 | .App { 9 | /* Super basic container to fill the page and center contents */ 10 | width: 100vw; 11 | height: 100%; 12 | min-height: 100vh; 13 | display: flex; 14 | flex-flow: column nowrap; 15 | justify-content: center; 16 | align-items: center; 17 | } 18 | 19 | a { 20 | color: #61dafb; 21 | } 22 | 23 | main { 24 | padding: 2rem; 25 | text-align: center; 26 | box-sizing: border-box; 27 | width: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /react-table/1-basics/src/App.js: -------------------------------------------------------------------------------- 1 | import useData from './utils/useData.js'; 2 | import Table from './Table.js'; 3 | 4 | import './App.css'; 5 | 6 | function App() { 7 | const data = useData(); 8 | return ( 9 |
10 |
11 | 12 | 13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /react-table/1-basics/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /react-table/1-basics/src/Table.js: -------------------------------------------------------------------------------- 1 | import styles from './Table.module.css' 2 | 3 | export default function Table({ data: { headers, rows } }) { 4 | return ( 5 |
6 | 7 | {headers.map(h => )} 8 | 9 | 10 | {rows.map((row) => ( 11 | 12 | {row.map(cell => )} 13 | 14 | ))} 15 | 16 |
{h}
{cell}
17 | ); 18 | } -------------------------------------------------------------------------------- /react-table/1-basics/src/Table.module.css: -------------------------------------------------------------------------------- 1 | .Table { 2 | font-size: 1rem; 3 | text-align: left; 4 | border-collapse: collapse; 5 | width: 100%; 6 | } 7 | 8 | .Table td, .Table th { 9 | line-height: 2em; 10 | padding: 0 0.75em; 11 | border: 1px rgba(255, 255, 255, 0.75) solid; 12 | } 13 | 14 | .Table th { 15 | padding: 0.75em 0.75em; 16 | border-bottom-width: 2px; 17 | } -------------------------------------------------------------------------------- /react-table/1-basics/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /react-table/1-basics/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /react-table/1-basics/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /react-table/1-basics/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react-table/1-basics/src/utils/useData.js: -------------------------------------------------------------------------------- 1 | function randomFrom(array) { 2 | return array[Math.floor(Math.random() * array.length)]; 3 | } 4 | 5 | /** Make a silly word that rhymes with Goomba (the Mario mushroom enemies) */ 6 | function sillyWord() { 7 | const leadConsonants = ['B', 'D', 'F', 'G', 'L', 'T', 'V', 'Z']; 8 | const middles = ['oom', 'oon', 'um', 'un']; 9 | const midConsonants = ['b', 'd'] 10 | const ends = ['a', 'ah', 'u', 'uh', 'o']; 11 | 12 | const word = randomFrom(leadConsonants) + randomFrom(middles) + randomFrom(midConsonants) + randomFrom(ends); 13 | 14 | // Try again if we accidentally picked something offensive 15 | if (['Goombah'].includes(word)) return sillyWord(); 16 | else return word; 17 | } 18 | 19 | function sillyName() { 20 | return `${sillyWord()} ${sillyWord().substring(0, 3)}`; 21 | } 22 | 23 | export default function useData(numRows = 20, numCols = 5) { 24 | const headers = ['ID', 'Name', 'Friend', 'Score', 'Temperament']; 25 | const genFuncs = [ 26 | () => Math.ceil(Math.random() * 100), 27 | sillyName, 28 | sillyWord, 29 | () => Math.floor(Math.random() * 10_000) / 100, 30 | () => randomFrom(['Goofy', 'Wacky', 'Silly', 'Funny', 'Serious']), 31 | ]; 32 | return { 33 | headers: Array(numCols).fill(0).map((_, h) => headers[h % headers.length]), 34 | rows: Array(numRows).fill(0).map( 35 | () => Array(numCols).fill(0).map( 36 | (_, c) => genFuncs[c % genFuncs.length]() 37 | ) 38 | ), 39 | }; 40 | } -------------------------------------------------------------------------------- /react-table/2-react-table/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # Allowed because it's being hosted as a GitHub page. 13 | # Wonky, but it works in a pinch. 14 | # /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /react-table/2-react-table/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Basic Demo 2 | 3 | Demo for the second step in [this tutorial](https://blog.px.dev/tables-are-hard-2). 4 | 5 | [Back to Top](../README.md) 6 | 7 | In this step, we install the [react-table](https://react-table.tanstack.com) library and use it to render our basic data. 8 | 9 | How this was created: 10 | * Start with the result from [step 1](../1-basics/README.md) 11 | * `npm install react-table` 12 | * Follow `react-table`'s [quick start](https://react-table.tanstack.com/docs/quick-start) to convert our basic HTML table into a `react-table` consumer. 13 | * Changed the `makeData` function in `src/makeData.js` to provide what `react-table` expects. 14 | * Renamed `makeData` to `useData` in order to use `React.useMemo`. 15 | * Re-run `npm start` (need to restart this when changing dependencies and adding/renaming files) -------------------------------------------------------------------------------- /react-table/2-react-table/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/pixie-demos/react-table/2-react-table/build/static/css/main.42c8a56d.chunk.css", 4 | "main.js": "/pixie-demos/react-table/2-react-table/build/static/js/main.87594b58.chunk.js", 5 | "main.js.map": "/pixie-demos/react-table/2-react-table/build/static/js/main.87594b58.chunk.js.map", 6 | "runtime-main.js": "/pixie-demos/react-table/2-react-table/build/static/js/runtime-main.d56450fc.js", 7 | "runtime-main.js.map": "/pixie-demos/react-table/2-react-table/build/static/js/runtime-main.d56450fc.js.map", 8 | "static/js/2.7fa4c899.chunk.js": "/pixie-demos/react-table/2-react-table/build/static/js/2.7fa4c899.chunk.js", 9 | "static/js/2.7fa4c899.chunk.js.map": "/pixie-demos/react-table/2-react-table/build/static/js/2.7fa4c899.chunk.js.map", 10 | "static/js/3.22ca2655.chunk.js": "/pixie-demos/react-table/2-react-table/build/static/js/3.22ca2655.chunk.js", 11 | "static/js/3.22ca2655.chunk.js.map": "/pixie-demos/react-table/2-react-table/build/static/js/3.22ca2655.chunk.js.map", 12 | "index.html": "/pixie-demos/react-table/2-react-table/build/index.html", 13 | "static/css/main.42c8a56d.chunk.css.map": "/pixie-demos/react-table/2-react-table/build/static/css/main.42c8a56d.chunk.css.map", 14 | "static/js/2.7fa4c899.chunk.js.LICENSE.txt": "/pixie-demos/react-table/2-react-table/build/static/js/2.7fa4c899.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.d56450fc.js", 18 | "static/js/2.7fa4c899.chunk.js", 19 | "static/css/main.42c8a56d.chunk.css", 20 | "static/js/main.87594b58.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /react-table/2-react-table/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/2-react-table/build/favicon.ico -------------------------------------------------------------------------------- /react-table/2-react-table/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/2-react-table/build/logo192.png -------------------------------------------------------------------------------- /react-table/2-react-table/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/2-react-table/build/logo512.png -------------------------------------------------------------------------------- /react-table/2-react-table/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/2-react-table/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/2-react-table/build/static/css/main.42c8a56d.chunk.css: -------------------------------------------------------------------------------- 1 | body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.Table_Table__gTzsf{font-size:1rem;text-align:left;border-collapse:collapse;width:100%}.Table_Table__gTzsf td,.Table_Table__gTzsf th{line-height:2em;padding:0 .75em;border:1px solid hsla(0,0%,100%,.75)}.Table_Table__gTzsf th{padding:.75em;border-bottom-width:2px}.App{width:100vw;height:100%;min-height:100vh;display:flex;flex-flow:column nowrap;justify-content:center;align-items:center;background-color:#282c34;font-size:calc(10px + 2vmin);color:#fff}a{color:#61dafb}main{padding:2rem;text-align:center;box-sizing:border-box;width:100%} 2 | /*# sourceMappingURL=main.42c8a56d.chunk.css.map */ -------------------------------------------------------------------------------- /react-table/2-react-table/build/static/css/main.42c8a56d.chunk.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://src/index.css","webpack://src/Table.module.css","webpack://src/App.css"],"names":[],"mappings":"AAAA,KACE,QAAS,CACT,mJAEY,CACZ,kCAAmC,CACnC,iCACF,CAEA,KACE,yEAEF,CCZA,oBACE,cAAe,CACf,eAAgB,CAChB,wBAAyB,CACzB,UACF,CAEA,8CACE,eAAgB,CAChB,eAAiB,CACjB,oCACF,CAEA,uBACE,aAAsB,CACtB,uBACF,CChBA,KAEE,WAAY,CACZ,WAAY,CACZ,gBAAiB,CACjB,YAAa,CACb,uBAAwB,CACxB,sBAAuB,CACvB,kBAAmB,CAGnB,wBAAyB,CACzB,4BAA6B,CAC7B,UACF,CAEA,EACE,aACF,CAEA,KACE,YAAa,CACb,iBAAkB,CAClB,qBAAsB,CACtB,UACF","file":"main.42c8a56d.chunk.css","sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n",".Table {\n font-size: 1rem;\n text-align: left;\n border-collapse: collapse;\n width: 100%;\n}\n\n.Table td, .Table th {\n line-height: 2em;\n padding: 0 0.75em;\n border: 1px rgba(255, 255, 255, 0.75) solid;\n}\n\n.Table th {\n padding: 0.75em 0.75em;\n border-bottom-width: 2px;\n}",".App {\n /* Super basic container to fill the page and center contents */\n width: 100vw;\n height: 100%;\n min-height: 100vh;\n display: flex;\n flex-flow: column nowrap;\n justify-content: center;\n align-items: center;\n\n /* Make it look nice */\n background-color: #282c34;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\na {\n color: #61dafb;\n}\n\nmain {\n padding: 2rem;\n text-align: center;\n box-sizing: border-box;\n width: 100%;\n}\n"]} -------------------------------------------------------------------------------- /react-table/2-react-table/build/static/js/2.7fa4c899.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.20.2 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v17.0.2 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v17.0.2 26 | * react-jsx-runtime.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | 34 | /** @license React v17.0.2 35 | * react.production.min.js 36 | * 37 | * Copyright (c) Facebook, Inc. and its affiliates. 38 | * 39 | * This source code is licensed under the MIT license found in the 40 | * LICENSE file in the root directory of this source tree. 41 | */ 42 | -------------------------------------------------------------------------------- /react-table/2-react-table/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-table-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/pixie-demos/react-table/2-react-table/build", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.16.1", 8 | "@testing-library/react": "^11.2.7", 9 | "@testing-library/user-event": "^12.8.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "react-table": "^7.7.0", 14 | "web-vitals": "^1.1.2" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /react-table/2-react-table/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/2-react-table/public/favicon.ico -------------------------------------------------------------------------------- /react-table/2-react-table/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/2-react-table/public/logo192.png -------------------------------------------------------------------------------- /react-table/2-react-table/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/2-react-table/public/logo512.png -------------------------------------------------------------------------------- /react-table/2-react-table/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/2-react-table/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/2-react-table/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* Make it look nice */ 3 | background-color: #282c34; 4 | font-size: calc(10px + 2vmin); 5 | color: white; 6 | } 7 | 8 | .App { 9 | /* Super basic container to fill the page and center contents */ 10 | width: 100vw; 11 | height: 100%; 12 | min-height: 100vh; 13 | display: flex; 14 | flex-flow: column nowrap; 15 | justify-content: center; 16 | align-items: center; 17 | } 18 | 19 | a { 20 | color: #61dafb; 21 | } 22 | 23 | main { 24 | padding: 2rem; 25 | text-align: center; 26 | box-sizing: border-box; 27 | width: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /react-table/2-react-table/src/App.js: -------------------------------------------------------------------------------- 1 | import useData from './utils/useData.js'; 2 | import Table from './Table.js'; 3 | 4 | import './App.css'; 5 | 6 | function App() { 7 | const data = useData(); 8 | return ( 9 |
10 |
11 | 12 | 13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /react-table/2-react-table/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /react-table/2-react-table/src/Table.js: -------------------------------------------------------------------------------- 1 | import styles from './Table.module.css' 2 | import { useTable } from 'react-table'; 3 | 4 | export default function Table({ data: { columns, data } }) { 5 | const reactTable = useTable({ columns, data }); 6 | 7 | const { 8 | getTableProps, 9 | getTableBodyProps, 10 | headerGroups, 11 | rows, 12 | prepareRow 13 | } = reactTable; 14 | 15 | return ( 16 |
17 | 18 | {headerGroups.map(group => ( 19 | 20 | {group.headers.map(column => ( 21 | 24 | ))} 25 | 26 | ))} 27 | 28 | 29 | {rows.map((row) => { 30 | prepareRow(row); 31 | return ( 32 | 33 | {row.cells.map(cell => ( 34 | 37 | ))} 38 | 39 | ); 40 | })} 41 | 42 |
22 | {column.render('Header')} 23 |
35 | {cell.render('Cell')} 36 |
43 | ); 44 | } -------------------------------------------------------------------------------- /react-table/2-react-table/src/Table.module.css: -------------------------------------------------------------------------------- 1 | .Table { 2 | font-size: 1rem; 3 | text-align: left; 4 | border-collapse: collapse; 5 | width: 100%; 6 | } 7 | 8 | .Table td, .Table th { 9 | line-height: 2em; 10 | padding: 0 0.75em; 11 | border: 1px rgba(255, 255, 255, 0.75) solid; 12 | } 13 | 14 | .Table th { 15 | padding: 0.75em 0.75em; 16 | border-bottom-width: 2px; 17 | } -------------------------------------------------------------------------------- /react-table/2-react-table/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /react-table/2-react-table/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /react-table/2-react-table/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /react-table/2-react-table/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # Allowed because it's being hosted as a GitHub page. 13 | # Wonky, but it works in a pinch. 14 | # /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Basic Demo 2 | 3 | Demo for the third step in [this tutorial](https://blog.px.dev/tables-are-hard-2). 4 | 5 | [Back to Top](../README.md) 6 | 7 | In this step, we add filtering and sorting functionality. 8 | 9 | How this was created: 10 | * Start with the result from [step 2](../2-react-table/README.md) 11 | * Add filtering: 12 | * Create a basic `Filter` component for the user to type anything that might exist in the table's data 13 | * Import `useGlobalFilter` from `react-table` 14 | * Add it to the list of plugins in the `useTable` call 15 | * Call the `setGlobalFilter` function that it provides when the input in our new `Filter` component changes. 16 | * Add sorting: 17 | * Import `useSortBy` from `react-table` 18 | * Add it to the list of plugins like we did with `useGlobalFilter` 19 | * Add props to the table header to attach props and event handlers that `useSortBy` creates for us. 20 | * Add a visual representation of sort state, using props that `useSortBy` provides for us. -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/pixie-demos/react-table/3-sort-and-filter/build/static/css/main.d666c1a7.chunk.css", 4 | "main.js": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/main.0c402462.chunk.js", 5 | "main.js.map": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/main.0c402462.chunk.js.map", 6 | "runtime-main.js": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/runtime-main.298b9c6d.js", 7 | "runtime-main.js.map": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/runtime-main.298b9c6d.js.map", 8 | "static/js/2.612c659f.chunk.js": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/2.612c659f.chunk.js", 9 | "static/js/2.612c659f.chunk.js.map": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/2.612c659f.chunk.js.map", 10 | "static/js/3.f684159d.chunk.js": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/3.f684159d.chunk.js", 11 | "static/js/3.f684159d.chunk.js.map": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/3.f684159d.chunk.js.map", 12 | "index.html": "/pixie-demos/react-table/3-sort-and-filter/build/index.html", 13 | "static/css/main.d666c1a7.chunk.css.map": "/pixie-demos/react-table/3-sort-and-filter/build/static/css/main.d666c1a7.chunk.css.map", 14 | "static/js/2.612c659f.chunk.js.LICENSE.txt": "/pixie-demos/react-table/3-sort-and-filter/build/static/js/2.612c659f.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.298b9c6d.js", 18 | "static/js/2.612c659f.chunk.js", 19 | "static/css/main.d666c1a7.chunk.css", 20 | "static/js/main.0c402462.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/3-sort-and-filter/build/favicon.ico -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/3-sort-and-filter/build/logo192.png -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/3-sort-and-filter/build/logo512.png -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/build/static/css/main.d666c1a7.chunk.css: -------------------------------------------------------------------------------- 1 | body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.Table_Table__gTzsf{font-size:1rem;text-align:left;border-collapse:collapse;width:100%}.Table_Table__gTzsf td,.Table_Table__gTzsf th{line-height:2em;padding:0 .75em;border:1px solid hsla(0,0%,100%,.75)}.Table_Table__gTzsf th{padding:.75em;border-bottom-width:2px}.Filter_Filter__3qIm_{width:100%;display:flex;justify-content:flex-start;margin-bottom:1rem}.App{width:100vw;height:100%;min-height:100vh;display:flex;flex-flow:column nowrap;justify-content:center;align-items:center;background-color:#282c34;font-size:calc(10px + 2vmin);color:#fff}a{color:#61dafb}main{padding:2rem;text-align:center;box-sizing:border-box;width:100%} 2 | /*# sourceMappingURL=main.d666c1a7.chunk.css.map */ -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/build/static/js/2.612c659f.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.20.2 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v17.0.2 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v17.0.2 26 | * react-jsx-runtime.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | 34 | /** @license React v17.0.2 35 | * react.production.min.js 36 | * 37 | * Copyright (c) Facebook, Inc. and its affiliates. 38 | * 39 | * This source code is licensed under the MIT license found in the 40 | * LICENSE file in the root directory of this source tree. 41 | */ 42 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-table-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/pixie-demos/react-table/3-sort-and-filter/build", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.16.1", 8 | "@testing-library/react": "^11.2.7", 9 | "@testing-library/user-event": "^12.8.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "react-table": "^7.7.0", 14 | "web-vitals": "^1.1.2" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/3-sort-and-filter/public/favicon.ico -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/3-sort-and-filter/public/logo192.png -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/3-sort-and-filter/public/logo512.png -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* Make it look nice */ 3 | background-color: #282c34; 4 | font-size: calc(10px + 2vmin); 5 | color: white; 6 | } 7 | 8 | .App { 9 | /* Super basic container to fill the page and center contents */ 10 | width: 100vw; 11 | height: 100%; 12 | min-height: 100vh; 13 | display: flex; 14 | flex-flow: column nowrap; 15 | justify-content: center; 16 | align-items: center; 17 | } 18 | 19 | a { 20 | color: #61dafb; 21 | } 22 | 23 | main { 24 | padding: 2rem; 25 | text-align: center; 26 | box-sizing: border-box; 27 | width: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/App.js: -------------------------------------------------------------------------------- 1 | import useData from './utils/useData.js'; 2 | import Table from './Table.js'; 3 | 4 | import './App.css'; 5 | 6 | function App() { 7 | const data = useData(); 8 | return ( 9 |
10 |
11 | 12 | 13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/Filter.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import styles from './Filter.module.css'; 4 | 5 | export default function Filter({ onChange }) { 6 | const [value, setValue] = React.useState(''); 7 | 8 | const onChangeWrapper = React.useCallback((event) => { 9 | const v = event.target.value.trim(); 10 | setValue(v); 11 | onChange(v); 12 | }, [onChange]); 13 | 14 | return ( 15 |
16 | 17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/Filter.module.css: -------------------------------------------------------------------------------- 1 | .Filter { 2 | width: 100%; 3 | display: flex; 4 | justify-content: flex-start; 5 | margin-bottom: 1rem; 6 | } -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/Table.module.css: -------------------------------------------------------------------------------- 1 | .Table { 2 | font-size: 1rem; 3 | text-align: left; 4 | border-collapse: collapse; 5 | width: 100%; 6 | } 7 | 8 | .Table td, .Table th { 9 | line-height: 2em; 10 | padding: 0 0.75em; 11 | border: 1px rgba(255, 255, 255, 0.75) solid; 12 | } 13 | 14 | .Table th { 15 | padding: 0.75em 0.75em; 16 | border-bottom-width: 2px; 17 | } -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /react-table/3-sort-and-filter/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react-table/4-column-controls/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # Allowed because it's being hosted as a GitHub page. 13 | # Wonky, but it works in a pinch. 14 | # /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /react-table/4-column-controls/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Basic Demo 2 | 3 | Demo for the fourth step in [this tutorial](https://blog.px.dev/tables-are-hard-2). 4 | 5 | [Back to Top](../README.md) 6 | 7 | In this step, we add features to resize, reorder, and hide columns. 8 | 9 | How this was created: 10 | * Start with the result from [step 3](../3-sort-filter/README.md) 11 | * Add column resizing: 12 | * Add `useFlexLayout` from `react-table` to define how column widths should be calculated 13 | * Add `useResizeColumns` from `react-table` to add logic for manual resizing 14 | * When combined with `useFlexLayout`, the table remains full width, and resizing a column also resizes other columns to retain the same combined width. 15 | * If we had used `useBlockLayout` instead, the table's total width would change as the columns do, and the default width would not be 100%. 16 | * Using the props that `useResizeColumns` adds to each column, create a resize handle that invokes the plugin's methods. 17 | * Slightly adjust structure in HTML and CSS for the `Table` component so that sort and resize controls don't interfere with each other. 18 | * Add column hiding: 19 | * This one doesn't need a plugin to be imported; it's already provided by `useTable` 20 | * Create a `ColumnSelector` component, which takes the `getToggleHiddenProps` method from each column in `useTable(...).allColumns` to make a checkbox toggle that column's visibility -------------------------------------------------------------------------------- /react-table/4-column-controls/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/pixie-demos/react-table/4-column-controls/build/static/css/main.611aeaed.chunk.css", 4 | "main.js": "/pixie-demos/react-table/4-column-controls/build/static/js/main.df0ba673.chunk.js", 5 | "main.js.map": "/pixie-demos/react-table/4-column-controls/build/static/js/main.df0ba673.chunk.js.map", 6 | "runtime-main.js": "/pixie-demos/react-table/4-column-controls/build/static/js/runtime-main.9d7ab708.js", 7 | "runtime-main.js.map": "/pixie-demos/react-table/4-column-controls/build/static/js/runtime-main.9d7ab708.js.map", 8 | "static/js/2.ce919d20.chunk.js": "/pixie-demos/react-table/4-column-controls/build/static/js/2.ce919d20.chunk.js", 9 | "static/js/2.ce919d20.chunk.js.map": "/pixie-demos/react-table/4-column-controls/build/static/js/2.ce919d20.chunk.js.map", 10 | "static/js/3.acf92f0f.chunk.js": "/pixie-demos/react-table/4-column-controls/build/static/js/3.acf92f0f.chunk.js", 11 | "static/js/3.acf92f0f.chunk.js.map": "/pixie-demos/react-table/4-column-controls/build/static/js/3.acf92f0f.chunk.js.map", 12 | "index.html": "/pixie-demos/react-table/4-column-controls/build/index.html", 13 | "static/css/main.611aeaed.chunk.css.map": "/pixie-demos/react-table/4-column-controls/build/static/css/main.611aeaed.chunk.css.map", 14 | "static/js/2.ce919d20.chunk.js.LICENSE.txt": "/pixie-demos/react-table/4-column-controls/build/static/js/2.ce919d20.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.9d7ab708.js", 18 | "static/js/2.ce919d20.chunk.js", 19 | "static/css/main.611aeaed.chunk.css", 20 | "static/js/main.df0ba673.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /react-table/4-column-controls/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/4-column-controls/build/favicon.ico -------------------------------------------------------------------------------- /react-table/4-column-controls/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/4-column-controls/build/logo192.png -------------------------------------------------------------------------------- /react-table/4-column-controls/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/4-column-controls/build/logo512.png -------------------------------------------------------------------------------- /react-table/4-column-controls/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/4-column-controls/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/4-column-controls/build/static/css/main.611aeaed.chunk.css: -------------------------------------------------------------------------------- 1 | body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.Table_Table__gTzsf{font-size:1rem;text-align:left;border-collapse:collapse;width:100%}.Table_Table__gTzsf td,.Table_Table__gTzsf th{line-height:2em;padding:0 .75em;border:1px solid hsla(0,0%,100%,.75);text-overflow:ellipsis;white-space:nowrap;overflow:hidden;min-width:2rem}.Table_Table__gTzsf th{max-height:3.5em;padding:.75em;border-bottom-width:2px;position:relative}.Table_ResizeHandle__1LDIp{-webkit-user-select:none;-ms-user-select:none;user-select:none;display:inline-block;position:absolute;top:50%;right:0;-webkit-transform:translateY(-50%);transform:translateY(-50%);opacity:.8}.Table_ResizeHandleActive__-UEDL{opacity:1}.Filter_Filter__3qIm_{width:100%;display:flex;justify-content:flex-start;margin-bottom:1rem}.ColumnSelector_ColumnSelector__1LtuL{font-size:1rem;margin-bottom:1rem}.ColumnSelector_Checkbox__3CcNf,.ColumnSelector_Label__Znnco{text-align:left}.App{width:100vw;height:100%;min-height:100vh;display:flex;flex-flow:column nowrap;justify-content:center;align-items:center;background-color:#282c34;font-size:calc(10px + 2vmin);color:#fff}a{color:#61dafb}main{padding:2rem;text-align:center;box-sizing:border-box;width:100%} 2 | /*# sourceMappingURL=main.611aeaed.chunk.css.map */ -------------------------------------------------------------------------------- /react-table/4-column-controls/build/static/js/2.ce919d20.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.20.2 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v17.0.2 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v17.0.2 26 | * react-jsx-runtime.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | 34 | /** @license React v17.0.2 35 | * react.production.min.js 36 | * 37 | * Copyright (c) Facebook, Inc. and its affiliates. 38 | * 39 | * This source code is licensed under the MIT license found in the 40 | * LICENSE file in the root directory of this source tree. 41 | */ 42 | -------------------------------------------------------------------------------- /react-table/4-column-controls/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-table-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/pixie-demos/react-table/4-column-controls/build", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.16.1", 8 | "@testing-library/react": "^11.2.7", 9 | "@testing-library/user-event": "^12.8.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "react-table": "^7.7.0", 14 | "web-vitals": "^1.1.2" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /react-table/4-column-controls/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/4-column-controls/public/favicon.ico -------------------------------------------------------------------------------- /react-table/4-column-controls/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/4-column-controls/public/logo192.png -------------------------------------------------------------------------------- /react-table/4-column-controls/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/4-column-controls/public/logo512.png -------------------------------------------------------------------------------- /react-table/4-column-controls/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/4-column-controls/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/4-column-controls/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* Make it look nice */ 3 | background-color: #282c34; 4 | font-size: calc(10px + 2vmin); 5 | color: white; 6 | } 7 | 8 | .App { 9 | /* Super basic container to fill the page and center contents */ 10 | width: 100vw; 11 | height: 100%; 12 | min-height: 100vh; 13 | display: flex; 14 | flex-flow: column nowrap; 15 | justify-content: center; 16 | align-items: center; 17 | } 18 | 19 | a { 20 | color: #61dafb; 21 | } 22 | 23 | main { 24 | padding: 2rem; 25 | text-align: center; 26 | box-sizing: border-box; 27 | width: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /react-table/4-column-controls/src/App.js: -------------------------------------------------------------------------------- 1 | import useData from './utils/useData.js'; 2 | import Table from './Table.js'; 3 | 4 | import './App.css'; 5 | 6 | function App() { 7 | const data = useData(); 8 | return ( 9 |
10 |
11 |
12 | 13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /react-table/4-column-controls/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /react-table/4-column-controls/src/ColumnSelector.js: -------------------------------------------------------------------------------- 1 | import styles from './ColumnSelector.module.css'; 2 | 3 | export default function ColumnSelector({ columns }) { 4 | return ( 5 |
6 |
Show Columns:
7 |
8 | {columns.map(column => ( 9 |
10 | 14 |
15 | ))} 16 |
17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/4-column-controls/src/ColumnSelector.module.css: -------------------------------------------------------------------------------- 1 | .ColumnSelector { 2 | font-size: 1rem; 3 | margin-bottom: 1rem; 4 | } 5 | 6 | .Label { 7 | text-align: left; 8 | } 9 | 10 | .Checkbox { 11 | text-align: left; 12 | } -------------------------------------------------------------------------------- /react-table/4-column-controls/src/Filter.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import styles from './Filter.module.css'; 4 | 5 | export default function Filter({ onChange }) { 6 | const [value, setValue] = React.useState(''); 7 | 8 | const onChangeWrapper = React.useCallback((event) => { 9 | const v = event.target.value.trim(); 10 | setValue(v); 11 | onChange(v); 12 | }, [onChange]); 13 | 14 | return ( 15 |
16 | 17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/4-column-controls/src/Filter.module.css: -------------------------------------------------------------------------------- 1 | .Filter { 2 | width: 100%; 3 | display: flex; 4 | justify-content: flex-start; 5 | margin-bottom: 1rem; 6 | } -------------------------------------------------------------------------------- /react-table/4-column-controls/src/Table.module.css: -------------------------------------------------------------------------------- 1 | .Table { 2 | font-size: 1rem; 3 | text-align: left; 4 | border-collapse: collapse; 5 | width: 100%; 6 | } 7 | 8 | .Table td, .Table th { 9 | line-height: 2em; 10 | padding: 0 0.75em; 11 | border: 1px rgba(255, 255, 255, 0.75) solid; 12 | text-overflow: ellipsis; 13 | white-space: nowrap; 14 | overflow: hidden; 15 | min-width: 2rem; 16 | } 17 | 18 | .Table th { 19 | max-height: 3.5em; 20 | padding: 0.75em 0.75em; 21 | border-bottom-width: 2px; 22 | position: relative; 23 | } 24 | 25 | .ResizeHandle { 26 | user-select: none; 27 | display: inline-block; 28 | position: absolute; 29 | top: 50%; 30 | right: 0; 31 | transform: translate(0, -50%); 32 | opacity: 0.8; 33 | } 34 | 35 | .ResizeHandleActive { 36 | opacity: 1; 37 | } -------------------------------------------------------------------------------- /react-table/4-column-controls/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /react-table/4-column-controls/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /react-table/4-column-controls/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /react-table/4-column-controls/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # Allowed because it's being hosted as a GitHub page. 13 | # Wonky, but it works in a pinch. 14 | # /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Basic Demo 2 | 3 | Demo for the fifth step in [this tutorial](https://blog.px.dev/tables-are-hard-2). 4 | 5 | [Back to Top](../README.md) 6 | 7 | In this step, we render individual data cells with extra decoration. 8 | 9 | How this was created: 10 | * Start with the result from [step 4](../4-column-controls/README.md) 11 | * Add a `Cell` function to the object defining each column in `useData.js`. That's all it takes! -------------------------------------------------------------------------------- /react-table/5-fancy-cells/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/pixie-demos/react-table/5-fancy-cells/build/static/css/main.13a31467.chunk.css", 4 | "main.js": "/pixie-demos/react-table/5-fancy-cells/build/static/js/main.310358aa.chunk.js", 5 | "main.js.map": "/pixie-demos/react-table/5-fancy-cells/build/static/js/main.310358aa.chunk.js.map", 6 | "runtime-main.js": "/pixie-demos/react-table/5-fancy-cells/build/static/js/runtime-main.5a2cac45.js", 7 | "runtime-main.js.map": "/pixie-demos/react-table/5-fancy-cells/build/static/js/runtime-main.5a2cac45.js.map", 8 | "static/js/2.6db881a1.chunk.js": "/pixie-demos/react-table/5-fancy-cells/build/static/js/2.6db881a1.chunk.js", 9 | "static/js/2.6db881a1.chunk.js.map": "/pixie-demos/react-table/5-fancy-cells/build/static/js/2.6db881a1.chunk.js.map", 10 | "static/js/3.acf92f0f.chunk.js": "/pixie-demos/react-table/5-fancy-cells/build/static/js/3.acf92f0f.chunk.js", 11 | "static/js/3.acf92f0f.chunk.js.map": "/pixie-demos/react-table/5-fancy-cells/build/static/js/3.acf92f0f.chunk.js.map", 12 | "index.html": "/pixie-demos/react-table/5-fancy-cells/build/index.html", 13 | "static/css/main.13a31467.chunk.css.map": "/pixie-demos/react-table/5-fancy-cells/build/static/css/main.13a31467.chunk.css.map", 14 | "static/js/2.6db881a1.chunk.js.LICENSE.txt": "/pixie-demos/react-table/5-fancy-cells/build/static/js/2.6db881a1.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.5a2cac45.js", 18 | "static/js/2.6db881a1.chunk.js", 19 | "static/css/main.13a31467.chunk.css", 20 | "static/js/main.310358aa.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /react-table/5-fancy-cells/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/5-fancy-cells/build/favicon.ico -------------------------------------------------------------------------------- /react-table/5-fancy-cells/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/5-fancy-cells/build/logo192.png -------------------------------------------------------------------------------- /react-table/5-fancy-cells/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/5-fancy-cells/build/logo512.png -------------------------------------------------------------------------------- /react-table/5-fancy-cells/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/build/static/css/main.13a31467.chunk.css: -------------------------------------------------------------------------------- 1 | body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.Table_Table__gTzsf{font-size:1rem;text-align:left;border-collapse:collapse;width:100%}.Table_Table__gTzsf td,.Table_Table__gTzsf th{line-height:2em;padding:0 .75em;border:1px solid hsla(0,0%,100%,.75);text-overflow:ellipsis;white-space:nowrap;overflow:hidden;min-width:2rem}.Table_Table__gTzsf th{max-height:3.5em;padding:.75em;border-bottom-width:2px;position:relative}.Table_ResizeHandle__1LDIp{-webkit-user-select:none;-ms-user-select:none;user-select:none;display:inline-block;position:absolute;top:50%;right:0;-webkit-transform:translateY(-50%);transform:translateY(-50%);opacity:.8}.Table_ResizeHandleActive__-UEDL{opacity:1}.Filter_Filter__3qIm_{width:100%;display:flex;justify-content:flex-start;margin-bottom:1rem}.ColumnSelector_ColumnSelector__1LtuL{font-size:1rem;margin-bottom:1rem}.ColumnSelector_Checkbox__3CcNf,.ColumnSelector_Label__Znnco{text-align:left}body{background-color:#282c34;font-size:calc(10px + 2vmin);color:#fff}.App{width:100vw;height:100%;min-height:100vh;display:flex;flex-flow:column nowrap;justify-content:center;align-items:center}a{color:#61dafb}main{padding:2rem;text-align:center;box-sizing:border-box;width:100%} 2 | /*# sourceMappingURL=main.13a31467.chunk.css.map */ -------------------------------------------------------------------------------- /react-table/5-fancy-cells/build/static/js/2.6db881a1.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.20.2 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v17.0.2 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v17.0.2 26 | * react-jsx-runtime.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | 34 | /** @license React v17.0.2 35 | * react.production.min.js 36 | * 37 | * Copyright (c) Facebook, Inc. and its affiliates. 38 | * 39 | * This source code is licensed under the MIT license found in the 40 | * LICENSE file in the root directory of this source tree. 41 | */ 42 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-table-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/pixie-demos/react-table/5-fancy-cells/build", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.16.1", 8 | "@testing-library/react": "^11.2.7", 9 | "@testing-library/user-event": "^12.8.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "react-table": "^7.7.0", 14 | "web-vitals": "^1.1.2" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/5-fancy-cells/public/favicon.ico -------------------------------------------------------------------------------- /react-table/5-fancy-cells/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/5-fancy-cells/public/logo192.png -------------------------------------------------------------------------------- /react-table/5-fancy-cells/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/5-fancy-cells/public/logo512.png -------------------------------------------------------------------------------- /react-table/5-fancy-cells/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* Make it look nice */ 3 | background-color: #282c34; 4 | font-size: calc(10px + 2vmin); 5 | color: white; 6 | } 7 | 8 | .App { 9 | /* Super basic container to fill the page and center contents */ 10 | width: 100vw; 11 | height: 100%; 12 | min-height: 100vh; 13 | display: flex; 14 | flex-flow: column nowrap; 15 | justify-content: center; 16 | align-items: center; 17 | } 18 | 19 | a { 20 | color: #61dafb; 21 | } 22 | 23 | main { 24 | padding: 2rem; 25 | text-align: center; 26 | box-sizing: border-box; 27 | width: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/App.js: -------------------------------------------------------------------------------- 1 | import useData from './utils/useData.js'; 2 | import Table from './Table.js'; 3 | 4 | import './App.css'; 5 | 6 | function App() { 7 | const data = useData(); 8 | return ( 9 |
10 |
11 |
12 | 13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/ColumnSelector.js: -------------------------------------------------------------------------------- 1 | import styles from './ColumnSelector.module.css'; 2 | 3 | export default function ColumnSelector({ columns }) { 4 | return ( 5 |
6 |
Show Columns:
7 |
8 | {columns.map(column => ( 9 |
10 | 14 |
15 | ))} 16 |
17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/ColumnSelector.module.css: -------------------------------------------------------------------------------- 1 | .ColumnSelector { 2 | font-size: 1rem; 3 | margin-bottom: 1rem; 4 | } 5 | 6 | .Label { 7 | text-align: left; 8 | } 9 | 10 | .Checkbox { 11 | text-align: left; 12 | } -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/Filter.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import styles from './Filter.module.css'; 4 | 5 | export default function Filter({ onChange }) { 6 | const [value, setValue] = React.useState(''); 7 | 8 | const onChangeWrapper = React.useCallback((event) => { 9 | const v = event.target.value.trim(); 10 | setValue(v); 11 | onChange(v); 12 | }, [onChange]); 13 | 14 | return ( 15 |
16 | 17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/Filter.module.css: -------------------------------------------------------------------------------- 1 | .Filter { 2 | width: 100%; 3 | display: flex; 4 | justify-content: flex-start; 5 | margin-bottom: 1rem; 6 | } -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/Table.module.css: -------------------------------------------------------------------------------- 1 | .Table { 2 | font-size: 1rem; 3 | text-align: left; 4 | border-collapse: collapse; 5 | width: 100%; 6 | } 7 | 8 | .Table td, .Table th { 9 | line-height: 2em; 10 | padding: 0 0.75em; 11 | border: 1px rgba(255, 255, 255, 0.75) solid; 12 | text-overflow: ellipsis; 13 | white-space: nowrap; 14 | overflow: hidden; 15 | min-width: 2rem; 16 | } 17 | 18 | .Table th { 19 | max-height: 3.5em; 20 | padding: 0.75em 0.75em; 21 | border-bottom-width: 2px; 22 | position: relative; 23 | } 24 | 25 | .ResizeHandle { 26 | user-select: none; 27 | display: inline-block; 28 | position: absolute; 29 | top: 50%; 30 | right: 0; 31 | transform: translate(0, -50%); 32 | opacity: 0.8; 33 | } 34 | 35 | .ResizeHandleActive { 36 | opacity: 1; 37 | } -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /react-table/5-fancy-cells/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react-table/6-new-base/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # Allowed because it's being hosted as a GitHub page. 13 | # Wonky, but it works in a pinch. 14 | # /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /react-table/6-new-base/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Basic Demo 2 | 3 | Demo for the initial setup in [this tutorial](https://blog.px.dev/tables-are-hard-3). 4 | 5 | [Back to Top](../README.md) 6 | 7 | In this step, we adjust the final result from [the previous tutorial](https://blog.px.dev/tables-are-hard-2) to prepare for streaming data. 8 | 9 | How this was created: 10 | * Start with the result from [step 5](../5-fancy-cells/README.md) of the previous 11 | * Clean up the styles to simplify them and prepare for future steps 12 | * Change `useData.js` to emit log-like data, and prepare it to emit a stream of data -------------------------------------------------------------------------------- /react-table/6-new-base/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/pixie-demos/react-table/6-new-base/build/static/css/main.99c788ec.chunk.css", 4 | "main.js": "/pixie-demos/react-table/6-new-base/build/static/js/main.8d5fe1bc.chunk.js", 5 | "main.js.map": "/pixie-demos/react-table/6-new-base/build/static/js/main.8d5fe1bc.chunk.js.map", 6 | "runtime-main.js": "/pixie-demos/react-table/6-new-base/build/static/js/runtime-main.69a857c1.js", 7 | "runtime-main.js.map": "/pixie-demos/react-table/6-new-base/build/static/js/runtime-main.69a857c1.js.map", 8 | "static/js/2.11d22c4e.chunk.js": "/pixie-demos/react-table/6-new-base/build/static/js/2.11d22c4e.chunk.js", 9 | "static/js/2.11d22c4e.chunk.js.map": "/pixie-demos/react-table/6-new-base/build/static/js/2.11d22c4e.chunk.js.map", 10 | "static/js/3.e7c438f0.chunk.js": "/pixie-demos/react-table/6-new-base/build/static/js/3.e7c438f0.chunk.js", 11 | "static/js/3.e7c438f0.chunk.js.map": "/pixie-demos/react-table/6-new-base/build/static/js/3.e7c438f0.chunk.js.map", 12 | "index.html": "/pixie-demos/react-table/6-new-base/build/index.html", 13 | "static/css/main.99c788ec.chunk.css.map": "/pixie-demos/react-table/6-new-base/build/static/css/main.99c788ec.chunk.css.map", 14 | "static/js/2.11d22c4e.chunk.js.LICENSE.txt": "/pixie-demos/react-table/6-new-base/build/static/js/2.11d22c4e.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.69a857c1.js", 18 | "static/js/2.11d22c4e.chunk.js", 19 | "static/css/main.99c788ec.chunk.css", 20 | "static/js/main.8d5fe1bc.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /react-table/6-new-base/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/6-new-base/build/favicon.ico -------------------------------------------------------------------------------- /react-table/6-new-base/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/6-new-base/build/logo192.png -------------------------------------------------------------------------------- /react-table/6-new-base/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/6-new-base/build/logo512.png -------------------------------------------------------------------------------- /react-table/6-new-base/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/6-new-base/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/6-new-base/build/static/js/2.11d22c4e.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.20.2 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v17.0.2 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v17.0.2 26 | * react-jsx-runtime.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | 34 | /** @license React v17.0.2 35 | * react.production.min.js 36 | * 37 | * Copyright (c) Facebook, Inc. and its affiliates. 38 | * 39 | * This source code is licensed under the MIT license found in the 40 | * LICENSE file in the root directory of this source tree. 41 | */ 42 | -------------------------------------------------------------------------------- /react-table/6-new-base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-table-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/pixie-demos/react-table/6-new-base/build", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.16.1", 8 | "@testing-library/react": "^11.2.7", 9 | "@testing-library/user-event": "^12.8.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "react-table": "^7.7.0", 14 | "web-vitals": "^1.1.2" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": [ 24 | "react-app", 25 | "react-app/jest" 26 | ] 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /react-table/6-new-base/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/6-new-base/public/favicon.ico -------------------------------------------------------------------------------- /react-table/6-new-base/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/6-new-base/public/logo192.png -------------------------------------------------------------------------------- /react-table/6-new-base/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/6-new-base/public/logo512.png -------------------------------------------------------------------------------- /react-table/6-new-base/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/6-new-base/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/6-new-base/src/App.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { useStaticData } from './utils/useData.js'; 4 | import Table from './Table.js'; 5 | 6 | import './App.css'; 7 | 8 | function App() { 9 | const data = useStaticData(100); 10 | return ( 11 |
12 |
13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /react-table/6-new-base/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /react-table/6-new-base/src/ColumnSelector.js: -------------------------------------------------------------------------------- 1 | import styles from './ColumnSelector.module.css'; 2 | 3 | export default function ColumnSelector({ columns }) { 4 | return ( 5 |
6 |
Show Columns:
7 |
8 | {columns.map(column => ( 9 |
10 | 14 |
15 | ))} 16 |
17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/6-new-base/src/ColumnSelector.module.css: -------------------------------------------------------------------------------- 1 | .ColumnSelector { 2 | font-size: 1rem; 3 | margin-bottom: 1rem; 4 | } 5 | 6 | .Label { 7 | text-align: left; 8 | } 9 | 10 | .Checkbox { 11 | text-align: left; 12 | } -------------------------------------------------------------------------------- /react-table/6-new-base/src/Filter.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import styles from './Filter.module.css'; 4 | 5 | export default function Filter({ onChange }) { 6 | const [value, setValue] = React.useState(''); 7 | 8 | const onChangeWrapper = React.useCallback((event) => { 9 | const v = event.target.value.trim(); 10 | setValue(v); 11 | onChange(v); 12 | }, [onChange]); 13 | 14 | return ( 15 |
16 | 17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/6-new-base/src/Filter.module.css: -------------------------------------------------------------------------------- 1 | .Filter { 2 | width: 100%; 3 | display: flex; 4 | justify-content: flex-start; 5 | margin-bottom: 1rem; 6 | } -------------------------------------------------------------------------------- /react-table/6-new-base/src/Table.css: -------------------------------------------------------------------------------- 1 | .Table-root { 2 | min-height: 100%; 3 | width: 100%; 4 | overflow-x: hidden; 5 | } 6 | 7 | .Table { 8 | box-sizing: border-box; 9 | max-width: 100%; 10 | max-height: 100vw; 11 | overflow: auto; 12 | } 13 | 14 | .Cell-Timestamp { 15 | font-family: monospace; 16 | color: var(--white); 17 | } 18 | 19 | .Cell-Latency.bad { color: var(--deep-orange-400); } 20 | .Cell-Latency.weak { color: var(--yellow-400); } 21 | .Cell-Latency.good { color: var(--green-400); } 22 | 23 | .Cell-Endpoint { 24 | font-family: monospace; 25 | } 26 | 27 | .Cell-StatusCode.range-200 { color: var(--green-400); } 28 | .Cell-StatusCode.range-300 { color: var(--cyan-400); } 29 | .Cell-StatusCode.range-400 { color: var(--orange-400); } 30 | .Cell-StatusCode.range-500 { color: var(--red-400); } -------------------------------------------------------------------------------- /react-table/6-new-base/src/Table.module.css: -------------------------------------------------------------------------------- 1 | .Table { 2 | font-size: 1rem; 3 | text-align: left; 4 | border-collapse: collapse; 5 | width: 100%; 6 | } 7 | 8 | .Table td, .Table th { 9 | line-height: 2em; 10 | padding: 0 0.75em; 11 | border: 1px rgba(255, 255, 255, 0.75) solid; 12 | text-overflow: ellipsis; 13 | white-space: nowrap; 14 | overflow: hidden; 15 | min-width: 2rem; 16 | } 17 | 18 | .Table th { 19 | max-height: 3.5em; 20 | padding: 0.75em 0.75em; 21 | border-bottom-width: 2px; 22 | position: relative; 23 | } 24 | 25 | .ResizeHandle { 26 | user-select: none; 27 | display: inline-block; 28 | position: absolute; 29 | top: 50%; 30 | right: 0; 31 | transform: translate(0, -50%); 32 | opacity: 0.8; 33 | } 34 | 35 | .ResizeHandleActive { 36 | opacity: 1; 37 | } -------------------------------------------------------------------------------- /react-table/6-new-base/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /react-table/6-new-base/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /react-table/6-new-base/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /react-table/6-new-base/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # Allowed because it's being hosted as a GitHub page. 13 | # Wonky, but it works in a pinch. 14 | # /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Basic Demo 2 | 3 | Demo for the second setup in [this tutorial](https://blog.px.dev/tables-are-hard-3). 4 | 5 | [Back to Top](../README.md) 6 | 7 | In this step, we add virtual scrolling to the table to handle thousands of rows without hanging the browser. 8 | 9 | How this was created: 10 | * Start with the result from [step 1](../6-new-base/README.md) 11 | * `npm install react-window` 12 | * Use `FixedSizeList` from `react-window` within `Table.js`, which presents a few noticeable issues 13 | * Fix issues with a bit of DOM bounding box math and some CSS tweaks (`useScrollbarSize.js`, `useContainerSize.js`, `App.css`, `Table.module.css`) 14 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/pixie-demos/react-table/7-virtual-scrolling/build/static/css/main.aa168c71.chunk.css", 4 | "main.js": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/main.e0c0b0cc.chunk.js", 5 | "main.js.map": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/main.e0c0b0cc.chunk.js.map", 6 | "runtime-main.js": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/runtime-main.3fbad986.js", 7 | "runtime-main.js.map": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/runtime-main.3fbad986.js.map", 8 | "static/js/2.abf91ae0.chunk.js": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/2.abf91ae0.chunk.js", 9 | "static/js/2.abf91ae0.chunk.js.map": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/2.abf91ae0.chunk.js.map", 10 | "static/js/3.532f84a7.chunk.js": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/3.532f84a7.chunk.js", 11 | "static/js/3.532f84a7.chunk.js.map": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/3.532f84a7.chunk.js.map", 12 | "index.html": "/pixie-demos/react-table/7-virtual-scrolling/build/index.html", 13 | "static/css/main.aa168c71.chunk.css.map": "/pixie-demos/react-table/7-virtual-scrolling/build/static/css/main.aa168c71.chunk.css.map", 14 | "static/js/2.abf91ae0.chunk.js.LICENSE.txt": "/pixie-demos/react-table/7-virtual-scrolling/build/static/js/2.abf91ae0.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.3fbad986.js", 18 | "static/js/2.abf91ae0.chunk.js", 19 | "static/css/main.aa168c71.chunk.css", 20 | "static/js/main.e0c0b0cc.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/7-virtual-scrolling/build/favicon.ico -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/7-virtual-scrolling/build/logo192.png -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/7-virtual-scrolling/build/logo512.png -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/build/static/js/2.abf91ae0.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.20.2 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v17.0.2 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v17.0.2 26 | * react-jsx-runtime.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | 34 | /** @license React v17.0.2 35 | * react.production.min.js 36 | * 37 | * Copyright (c) Facebook, Inc. and its affiliates. 38 | * 39 | * This source code is licensed under the MIT license found in the 40 | * LICENSE file in the root directory of this source tree. 41 | */ 42 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-table-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/pixie-demos/react-table/7-virtual-scrolling/build", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.16.1", 8 | "@testing-library/react": "^11.2.7", 9 | "@testing-library/user-event": "^12.8.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "react-table": "^7.7.0", 14 | "react-window": "^1.8.6", 15 | "web-vitals": "^1.1.2" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": [ 25 | "react-app", 26 | "react-app/jest" 27 | ] 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/7-virtual-scrolling/public/favicon.ico -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/7-virtual-scrolling/public/logo192.png -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/7-virtual-scrolling/public/logo512.png -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/App.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { useStaticData } from './utils/useData.js'; 4 | import Table from './Table.js'; 5 | 6 | import './App.css'; 7 | 8 | function App() { 9 | const data = useStaticData(10_000); 10 | return ( 11 |
12 |
13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/ColumnSelector.js: -------------------------------------------------------------------------------- 1 | import styles from './ColumnSelector.module.css'; 2 | 3 | export default function ColumnSelector({ columns }) { 4 | return ( 5 |
6 |
Show Columns:
7 |
8 | {columns.map(column => ( 9 |
10 | 14 |
15 | ))} 16 |
17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/ColumnSelector.module.css: -------------------------------------------------------------------------------- 1 | .ColumnSelector { 2 | font-size: 1rem; 3 | margin-bottom: 1rem; 4 | } 5 | 6 | .Label { 7 | text-align: left; 8 | } 9 | 10 | .Checkbox { 11 | text-align: left; 12 | } -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/Filter.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import styles from './Filter.module.css'; 4 | 5 | export default function Filter({ onChange }) { 6 | const [value, setValue] = React.useState(''); 7 | 8 | const onChangeWrapper = React.useCallback((event) => { 9 | const v = event.target.value.trim(); 10 | setValue(v); 11 | onChange(v); 12 | }, [onChange]); 13 | 14 | return ( 15 |
16 | 17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/Filter.module.css: -------------------------------------------------------------------------------- 1 | .Filter { 2 | width: 100%; 3 | display: flex; 4 | justify-content: flex-start; 5 | margin-bottom: 1rem; 6 | } -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/Table.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | flex: 1 1 auto; 3 | max-height: 100%; 4 | 5 | display: flex; 6 | flex-flow: column nowrap; 7 | overflow: hidden; 8 | } 9 | 10 | .root > *:not(.fill) { 11 | flex: 0 0 auto; 12 | } 13 | 14 | .fill { 15 | flex: 1 1 auto; 16 | overflow: hidden; 17 | } 18 | 19 | .Table { 20 | display: table; 21 | font-size: 1rem; 22 | text-align: left; 23 | border-collapse: collapse; 24 | width: 100%; 25 | } 26 | 27 | .Table .Row { display: table-row; } 28 | 29 | .Table .BodyCell, .Table .HeaderCell { 30 | display: table-cell; 31 | line-height: 2em; 32 | padding: 0 0.75em; 33 | border: 1px rgba(255, 255, 255, 0.75) solid; 34 | text-overflow: ellipsis; 35 | white-space: nowrap; 36 | overflow: hidden; 37 | min-width: 2rem; 38 | } 39 | 40 | .Table .HeaderCell { 41 | max-height: 3.5em; 42 | padding: 0.75em 0.75em; 43 | border-bottom-width: 2px; 44 | position: relative; 45 | } 46 | 47 | .ResizeHandle { 48 | user-select: none; 49 | display: inline-block; 50 | position: absolute; 51 | top: 50%; 52 | right: 0; 53 | transform: translate(0, -50%); 54 | opacity: 0.8; 55 | } 56 | 57 | .ResizeHandleActive { 58 | opacity: 1; 59 | } 60 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/utils/useContainerSize.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Oversimplified way to get the scroll container dimensions of an element. 5 | * If those dimensions vary with the size of those children, and those children try to use this, 6 | * there will be a loop. Use a more complex technique like `react-virtualized-autosizer` for those scenarios. 7 | */ 8 | export function useContainerSize(el) { 9 | return React.useMemo(() => { 10 | if (el) { 11 | return { 12 | width: el.clientWidth, 13 | height: el.clientHeight, 14 | }; 15 | } 16 | 17 | return { width: 0, height: 0 }; 18 | }, [el]); 19 | } 20 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/utils/useData.css: -------------------------------------------------------------------------------- 1 | .Cell-Timestamp { 2 | font-family: monospace; 3 | color: var(--white); 4 | } 5 | 6 | .Cell-Latency.bad { color: var(--deep-orange-400); } 7 | .Cell-Latency.weak { color: var(--yellow-400); } 8 | .Cell-Latency.good { color: var(--green-400); } 9 | 10 | .Cell-Endpoint { 11 | font-family: monospace; 12 | } 13 | 14 | .Cell-StatusCode.range-200 { color: var(--green-400); } 15 | .Cell-StatusCode.range-300 { color: var(--cyan-400); } 16 | .Cell-StatusCode.range-400 { color: var(--orange-400); } 17 | .Cell-StatusCode.range-500 { color: var(--red-400); } 18 | -------------------------------------------------------------------------------- /react-table/7-virtual-scrolling/src/utils/useScrollbarSize.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Determines the dimensions of the browser scrollbars when they would be shown. 5 | * Browsers may overlay scrollbars rather than putting them in-layout. In those cases they're treated as 0-width/height. 6 | */ 7 | export function useScrollbarSize() { 8 | return React.useMemo(() => { 9 | const scroller = document.createElement('div'); 10 | scroller.setAttribute('style', 'width: 100vw; height: 100vh; overflow: scroll; position: absolute; top: -100vh;'); 11 | document.body.appendChild(scroller); 12 | const width = scroller.offsetWidth - scroller.clientWidth; 13 | const height = scroller.offsetHeight - scroller.clientHeight; 14 | document.body.removeChild(scroller); 15 | return { width, height }; 16 | }, []); 17 | } 18 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | # Allowed because it's being hosted as a GitHub page. 13 | # Wonky, but it works in a pinch. 14 | # /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Basic Demo 2 | 3 | Demo for the second setup in [this tutorial](https://blog.px.dev/tables-are-hard-3). 4 | 5 | [Back to Top](../README.md) 6 | 7 | In this step, we add streaming data to a table that already has virtual scrolling, filtering, and sorting. 8 | Then we update these existing features to account for the data rapidly changing underneath them. 9 | 10 | How this was created: 11 | * Start with the result from [step 2](../7-virtual-scrolling/README.md) 12 | * Modify `useData.js` and `App.js` to use data that adds a batch new rows every second, which shows several issues: 13 | * Scroll position jump to the top every time a batch is added 14 | * Virtual scrolling doesn't notice this until you scroll again 15 | * Sorting and column resizing both reset every time a batch comes in 16 | * Fix sorting and column resizing with one-line settings changes for `react-table` 17 | * Set the default sort column to timestamp (ascending), so that new rows are appended at the bottom. 18 | * Clicking on the timestamp column to make it descending makes leaving the scrollbar at the top show updates live! 19 | * Fix scroll resetting / rendering issues with a bit of React.memo juggling 20 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/build/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/pixie-demos/react-table/8-streaming-data/build/static/css/main.240826cc.chunk.css", 4 | "main.js": "/pixie-demos/react-table/8-streaming-data/build/static/js/main.49cdad53.chunk.js", 5 | "main.js.map": "/pixie-demos/react-table/8-streaming-data/build/static/js/main.49cdad53.chunk.js.map", 6 | "runtime-main.js": "/pixie-demos/react-table/8-streaming-data/build/static/js/runtime-main.eed26c3e.js", 7 | "runtime-main.js.map": "/pixie-demos/react-table/8-streaming-data/build/static/js/runtime-main.eed26c3e.js.map", 8 | "static/js/2.11302f19.chunk.js": "/pixie-demos/react-table/8-streaming-data/build/static/js/2.11302f19.chunk.js", 9 | "static/js/2.11302f19.chunk.js.map": "/pixie-demos/react-table/8-streaming-data/build/static/js/2.11302f19.chunk.js.map", 10 | "static/js/3.656f3982.chunk.js": "/pixie-demos/react-table/8-streaming-data/build/static/js/3.656f3982.chunk.js", 11 | "static/js/3.656f3982.chunk.js.map": "/pixie-demos/react-table/8-streaming-data/build/static/js/3.656f3982.chunk.js.map", 12 | "index.html": "/pixie-demos/react-table/8-streaming-data/build/index.html", 13 | "static/css/main.240826cc.chunk.css.map": "/pixie-demos/react-table/8-streaming-data/build/static/css/main.240826cc.chunk.css.map", 14 | "static/js/2.11302f19.chunk.js.LICENSE.txt": "/pixie-demos/react-table/8-streaming-data/build/static/js/2.11302f19.chunk.js.LICENSE.txt" 15 | }, 16 | "entrypoints": [ 17 | "static/js/runtime-main.eed26c3e.js", 18 | "static/js/2.11302f19.chunk.js", 19 | "static/css/main.240826cc.chunk.css", 20 | "static/js/main.49cdad53.chunk.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /react-table/8-streaming-data/build/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/8-streaming-data/build/favicon.ico -------------------------------------------------------------------------------- /react-table/8-streaming-data/build/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/8-streaming-data/build/logo192.png -------------------------------------------------------------------------------- /react-table/8-streaming-data/build/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/8-streaming-data/build/logo512.png -------------------------------------------------------------------------------- /react-table/8-streaming-data/build/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/build/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/build/static/js/2.11302f19.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /** @license React v0.20.2 8 | * scheduler.production.min.js 9 | * 10 | * Copyright (c) Facebook, Inc. and its affiliates. 11 | * 12 | * This source code is licensed under the MIT license found in the 13 | * LICENSE file in the root directory of this source tree. 14 | */ 15 | 16 | /** @license React v17.0.2 17 | * react-dom.production.min.js 18 | * 19 | * Copyright (c) Facebook, Inc. and its affiliates. 20 | * 21 | * This source code is licensed under the MIT license found in the 22 | * LICENSE file in the root directory of this source tree. 23 | */ 24 | 25 | /** @license React v17.0.2 26 | * react-jsx-runtime.production.min.js 27 | * 28 | * Copyright (c) Facebook, Inc. and its affiliates. 29 | * 30 | * This source code is licensed under the MIT license found in the 31 | * LICENSE file in the root directory of this source tree. 32 | */ 33 | 34 | /** @license React v17.0.2 35 | * react.production.min.js 36 | * 37 | * Copyright (c) Facebook, Inc. and its affiliates. 38 | * 39 | * This source code is licensed under the MIT license found in the 40 | * LICENSE file in the root directory of this source tree. 41 | */ 42 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-table-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "/pixie-demos/react-table/8-streaming-data/build", 6 | "dependencies": { 7 | "@testing-library/jest-dom": "^5.16.1", 8 | "@testing-library/react": "^11.2.7", 9 | "@testing-library/user-event": "^12.8.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "react-table": "^7.7.0", 14 | "react-window": "^1.8.6", 15 | "web-vitals": "^1.1.2" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": [ 25 | "react-app", 26 | "react-app/jest" 27 | ] 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/8-streaming-data/public/favicon.ico -------------------------------------------------------------------------------- /react-table/8-streaming-data/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/8-streaming-data/public/logo192.png -------------------------------------------------------------------------------- /react-table/8-streaming-data/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixie-io/pixie-demos/6806d843e10a01134db273fa7e713124128c5e89/react-table/8-streaming-data/public/logo512.png -------------------------------------------------------------------------------- /react-table/8-streaming-data/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/App.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { useStreamingData } from './utils/useData.js'; 4 | import Table from './Table.js'; 5 | 6 | import './App.css'; 7 | 8 | function App() { 9 | const data = useStreamingData(); 10 | return ( 11 |
12 |
13 | 14 | ); 15 | } 16 | 17 | export default App; 18 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/ColumnSelector.js: -------------------------------------------------------------------------------- 1 | import styles from './ColumnSelector.module.css'; 2 | 3 | export default function ColumnSelector({ columns }) { 4 | return ( 5 |
6 |
Show Columns:
7 |
8 | {columns.map(column => ( 9 |
10 | 14 |
15 | ))} 16 |
17 |
18 | ); 19 | } -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/ColumnSelector.module.css: -------------------------------------------------------------------------------- 1 | .ColumnSelector { 2 | font-size: 1rem; 3 | margin-bottom: 1rem; 4 | } 5 | 6 | .Label { 7 | text-align: left; 8 | } 9 | 10 | .Checkbox { 11 | text-align: left; 12 | } -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/Filter.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import styles from './Filter.module.css'; 4 | 5 | export default function Filter({ onChange }) { 6 | const [value, setValue] = React.useState(''); 7 | 8 | const onChangeWrapper = React.useCallback((event) => { 9 | setValue(event.target.value); 10 | onChange(event.target.value.trim()); 11 | }, [onChange]); 12 | 13 | return ( 14 |
15 | 16 |
17 | ); 18 | } -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/Filter.module.css: -------------------------------------------------------------------------------- 1 | .Filter { 2 | width: 100%; 3 | display: flex; 4 | justify-content: flex-start; 5 | margin-bottom: 1rem; 6 | } -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/Table.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | flex: 1 1 auto; 3 | max-height: 100%; 4 | 5 | display: flex; 6 | flex-flow: column nowrap; 7 | overflow: hidden; 8 | } 9 | 10 | .root > *:not(.fill) { 11 | flex: 0 0 auto; 12 | } 13 | 14 | .fill { 15 | flex: 1 1 auto; 16 | overflow: hidden; 17 | } 18 | 19 | .Table { 20 | display: table; 21 | font-size: 1rem; 22 | text-align: left; 23 | border-collapse: collapse; 24 | width: 100%; 25 | } 26 | 27 | .Table .Row { display: table-row; } 28 | 29 | .Table .BodyCell, .Table .HeaderCell { 30 | display: table-cell; 31 | line-height: 2em; 32 | padding: 0 0.75em; 33 | border: 1px rgba(255, 255, 255, 0.75) solid; 34 | text-overflow: ellipsis; 35 | white-space: nowrap; 36 | overflow: hidden; 37 | min-width: 2rem; 38 | } 39 | 40 | .Table .HeaderCell { 41 | max-height: 3.5em; 42 | padding: 0.75em 0.75em; 43 | border-bottom-width: 2px; 44 | position: relative; 45 | } 46 | 47 | .ResizeHandle { 48 | user-select: none; 49 | display: inline-block; 50 | position: absolute; 51 | top: 50%; 52 | right: 0; 53 | transform: translate(0, -50%); 54 | opacity: 0.8; 55 | } 56 | 57 | .ResizeHandleActive { 58 | opacity: 1; 59 | } 60 | 61 | .ViewportDetails { 62 | flex: 0 1 auto; 63 | font-size: 1rem; 64 | text-align: right; 65 | border-top: 1px white solid; 66 | padding-top: 1em; 67 | } 68 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/utils/useContainerSize.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Oversimplified way to get the scroll container dimensions of an element. 5 | * If those dimensions vary with the size of those children, and those children try to use this, 6 | * there will be a loop. Use a more complex technique like `react-virtualized-autosizer` for those scenarios. 7 | */ 8 | export function useContainerSize(el) { 9 | return React.useMemo(() => { 10 | if (el) { 11 | return { 12 | width: el.clientWidth, 13 | height: el.clientHeight, 14 | }; 15 | } 16 | 17 | return { width: 0, height: 0 }; 18 | }, [el]); 19 | } 20 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/utils/useData.css: -------------------------------------------------------------------------------- 1 | .Cell-Timestamp { 2 | font-family: monospace; 3 | color: var(--white); 4 | } 5 | 6 | .Cell-Latency.bad { color: var(--deep-orange-400); } 7 | .Cell-Latency.weak { color: var(--yellow-400); } 8 | .Cell-Latency.good { color: var(--green-400); } 9 | 10 | .Cell-Endpoint { 11 | font-family: monospace; 12 | } 13 | 14 | .Cell-StatusCode.range-200 { color: var(--green-400); } 15 | .Cell-StatusCode.range-300 { color: var(--cyan-400); } 16 | .Cell-StatusCode.range-400 { color: var(--orange-400); } 17 | .Cell-StatusCode.range-500 { color: var(--red-400); } 18 | -------------------------------------------------------------------------------- /react-table/8-streaming-data/src/utils/useScrollbarSize.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Determines the dimensions of the browser scrollbars when they would be shown. 5 | * Browsers may overlay scrollbars rather than putting them in-layout. In those cases they're treated as 0-width/height. 6 | */ 7 | export function useScrollbarSize() { 8 | return React.useMemo(() => { 9 | const scroller = document.createElement('div'); 10 | scroller.setAttribute('style', 'width: 100vw; height: 100vh; overflow: scroll; position: absolute; top: -100vh;'); 11 | document.body.appendChild(scroller); 12 | const width = scroller.offsetWidth - scroller.clientWidth; 13 | const height = scroller.offsetHeight - scroller.clientHeight; 14 | document.body.removeChild(scroller); 15 | return { width, height }; 16 | }, []); 17 | } 18 | -------------------------------------------------------------------------------- /react-table/README.md: -------------------------------------------------------------------------------- 1 | # Tables are Hard: Demos 2 | 3 | Demos for each tutorial in the series: [Tables are Hard](https://blog.px.dev/tables-are-hard-2). 4 | 5 | Each numbered directory is a step in the tutorials, and contains its own `README.md` with steps to create your own. 6 | 7 | ## Incremental Improvement 8 | * [Step 1: Basics](./1-basics/README.md) 9 | * [Step 2: Enter `react-table`](./2-react-table/README.md) 10 | * [Step 3: Sorting and Filtering](./3-sort-and-filter/README.md) 11 | * [Step 4: Sorting, Ordering, and Hiding Columns](./4-column-controls/README.md) 12 | * [Step 5: Fancy Cells](./5-fancy-cells/README.md) 13 | * [Step 6: New Base](./6-new-base/README.md) (for [part 3](https://blog.px.dev/tables-are-hard-3)) 14 | * [Step 7: Virtual Scrolling](./7-virtual-scrolling/README.md) 15 | * [Step 8: Streaming Data](./8-streaming-data/README.md) 16 | 17 | ## Instructions 18 | 19 | * Clone this repository. 20 | * Open a terminal in the directory for the part you want to run. 21 | * `npm install`, then `npm start`. 22 | * Open your browser to `localhost:3000`. 23 | * Play with the code however you like; the browser tab will refresh automatically. -------------------------------------------------------------------------------- /react-table/react-table.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": ".." 5 | } 6 | ], 7 | "settings": {} 8 | } -------------------------------------------------------------------------------- /simple-gotracing/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore IDE files. 2 | .idea 3 | -------------------------------------------------------------------------------- /simple-gotracing/Readme.md: -------------------------------------------------------------------------------- 1 | ## Demo of Dynamic Go Tracing 2 | 3 | A walk through of this demo is located [here](https://docs.px.dev/tutorials/custom-data/dynamic-go-logging/). 4 | 5 | ### Youtube Video 6 | 7 | [![Demo Video](https://img.youtube.com/vi/aH7PHSsiIPM/0.jpg)](https://www.youtube.com/watch?v=aH7PHSsiIPM) 8 | 9 | ### Directory structure 10 | 11 | - **app**: Contains the demo application we will be tracing. 12 | - **http\_trace\_uprobe**: HTTP tracer based on uprobes on net/http. 13 | - **http\_trace\_kprobe**: HTTP tracer based on kprobes. 14 | - **trace\_example**: BPF example of argument tracer. 15 | 16 | ## Building the code 17 | 18 | Simply run `make` in each of the sub-directories to build those underlying binaries. 19 | You will need to run these on a Linux machine with [bcc](https://github.com/iovisor/bcc/blob/master/INSTALL.md) installed. 20 | 21 | Docker build coming soon! 22 | -------------------------------------------------------------------------------- /simple-gotracing/app/.gitignore: -------------------------------------------------------------------------------- 1 | app -------------------------------------------------------------------------------- /simple-gotracing/app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine as builder 2 | 3 | RUN mkdir /build 4 | ADD . /build/ 5 | WORKDIR /build 6 | RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o main . 7 | 8 | FROM scratch 9 | COPY --from=builder /build/main /app/ 10 | EXPOSE 9090 11 | WORKDIR /app 12 | CMD ["./main"] 13 | -------------------------------------------------------------------------------- /simple-gotracing/app/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: app 3 | 4 | app: *.go 5 | go build -o $@ $^ 6 | 7 | clean: 8 | rm -f app 9 | -------------------------------------------------------------------------------- /simple-gotracing/app/k8s_manifest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: px-demo-gotracing 5 | --- 6 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 7 | kind: Deployment 8 | metadata: 9 | name: gotracing 10 | namespace: px-demo-gotracing 11 | spec: 12 | selector: 13 | matchLabels: 14 | app: gotracing 15 | template: 16 | metadata: 17 | labels: 18 | app: gotracing 19 | spec: 20 | containers: 21 | - name: app 22 | # NOTE: If you create a new image this line needs to be updated: 23 | image: gcr.io/pixie-prod/pixie-prod-artifacts/demos/simple-gotracing-example:latest 24 | ports: 25 | - containerPort: 9090 26 | --- 27 | apiVersion: v1 28 | kind: Service 29 | metadata: 30 | name: gotracing-svc 31 | namespace: px-demo-gotracing 32 | spec: 33 | selector: 34 | app: gotracing 35 | ports: 36 | - port: 9090 37 | -------------------------------------------------------------------------------- /simple-gotracing/capture_args.pxl: -------------------------------------------------------------------------------- 1 | # -*- mode: python; -*- 2 | 3 | # Copyright (c) Pixie Labs, Inc. 4 | # Licensed under the Apache License, Version 2.0 (the "License") 5 | 6 | import pxtrace 7 | import px 8 | 9 | # The UPID of the simple-gotracing-example server. You can 10 | # get the value of this by running: 11 | # px run px/upids -- --namespace px-demo-gotracing 12 | # The relevant UPID will be in the fourth column. 13 | upid = 'replace-me-with-upid' 14 | 15 | # This is the basic trace function. Every function call of 16 | # `main.computeE` is traced and the values are recorded into 17 | # a table as specified by the return value. 18 | # 19 | # To probe struct functions, see the notes here: 20 | # https://docs.px.dev/tutorials/custom-data/dynamic-go-logging/#formatting-the-pxtrace.probe-path 21 | @pxtrace.probe("main.computeE") 22 | def probe_func(): 23 | return [{ 24 | 'iterations': pxtrace.ArgExpr("iterations"), 25 | 'latency': pxtrace.FunctionLatency(), 26 | }] 27 | 28 | # This is the function that actually installs the tracepoint. 29 | # The arguments are: 30 | # Tracepoint name. 31 | # Output table name. 32 | # Name of the probe function. 33 | # The UPID. 34 | # The TTL of the tracepoint. It is updated each time the script is run. 35 | pxtrace.UpsertTracepoint('compute_e_data', 36 | 'compute_e_data', 37 | probe_func, 38 | px.uint128(upid), 39 | "5m") 40 | 41 | # This just writes the output into a table. 42 | px.display(px.DataFrame(table='compute_e_data')) 43 | -------------------------------------------------------------------------------- /simple-gotracing/go.mod: -------------------------------------------------------------------------------- 1 | module pixielabs.ai/pixie/demos/simple-gotracing 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/fatih/color v1.9.0 7 | github.com/iovisor/gobpf v0.0.0-20200614202714-e6b321d32103 8 | ) 9 | -------------------------------------------------------------------------------- /simple-gotracing/go.sum: -------------------------------------------------------------------------------- 1 | github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= 2 | github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= 3 | github.com/iovisor/gobpf v0.0.0-20200614202714-e6b321d32103 h1:U2+owsfuUe5xehsVEmLZW91zY1ce7z3/YCQjMLVb6Q4= 4 | github.com/iovisor/gobpf v0.0.0-20200614202714-e6b321d32103/go.mod h1:+5U5qu5UOu8YJ5oHVLvWKH7/Dr5QNHU7mZ2RfPEeXg8= 5 | github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= 6 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 7 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 8 | github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= 9 | github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= 10 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 11 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= 12 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 13 | -------------------------------------------------------------------------------- /simple-gotracing/http_trace_kprobe/.gitignore: -------------------------------------------------------------------------------- 1 | http_trace_kprobe 2 | -------------------------------------------------------------------------------- /simple-gotracing/http_trace_kprobe/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018- The Pixie Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # SPDX-License-Identifier: Apache-2.0 17 | 18 | all: http_trace_kprobe 19 | 20 | http_trace_kprobe: *.go 21 | go build -o $@ $^ 22 | 23 | clean: 24 | rm -f http_trace_kprobe 25 | -------------------------------------------------------------------------------- /simple-gotracing/http_trace_uprobe/.gitignore: -------------------------------------------------------------------------------- 1 | http_trace_uprobe -------------------------------------------------------------------------------- /simple-gotracing/http_trace_uprobe/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018- The Pixie Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # SPDX-License-Identifier: Apache-2.0 17 | 18 | all: http_trace_uprobe 19 | 20 | http_trace_uprobe: *.go 21 | go build -o $@ $^ 22 | 23 | clean: 24 | rm -f http_trace_uprobe 25 | -------------------------------------------------------------------------------- /simple-gotracing/trace_example/.gitignore: -------------------------------------------------------------------------------- 1 | trace 2 | -------------------------------------------------------------------------------- /simple-gotracing/trace_example/Makefile: -------------------------------------------------------------------------------- 1 | all: trace 2 | 3 | 4 | trace: *.go 5 | go build -o $@ $^ 6 | 7 | clean: 8 | rm -f trace 9 | -------------------------------------------------------------------------------- /simple-gotracing/trace_example/Readme.md: -------------------------------------------------------------------------------- 1 | ## Go Dynamic Tracepoint example. 2 | This is an example of using [gobpf](https://github.com/iovisor/gobpf) to trace arguments of the function for our example [application](https://github.com/pixie-io/pixie-demos/blob/main/simple-gotracing/app/app.go). 3 | 4 | ### Dependencies 5 | This requires [libbcc](https://github.com/iovisor/bcc/blob/master/INSTALL.md) to be installed. 6 | 7 | ### Build 8 | ``` 9 | go build trace.go 10 | ``` 11 | 12 | ### Run 13 | ``` 14 | ./trace --binary ./app # To trace the example app. 15 | ``` 16 | -------------------------------------------------------------------------------- /slack-alert-app/README.md: -------------------------------------------------------------------------------- 1 | # Slack Alerts using the Pixie API 2 | 3 | Code for the ["Slack Alerts using the Pixie API"](https://docs.px.dev/tutorials/integrations/slackbot-alert/) tutorial. 4 | 5 | If you have any questions, please reach out on our [Pixie Community Slack](https://slackin.px.dev/) or file a GitHub issue. 6 | -------------------------------------------------------------------------------- /slack-alert-app/go/go.mod: -------------------------------------------------------------------------------- 1 | module slackbot 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/slack-go/slack v0.8.0 7 | px.dev/pxapi v0.0.0-20210429075727-90459acf9e37 8 | ) 9 | -------------------------------------------------------------------------------- /slack-alert-app/go/http_errors.pxl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pixie Labs, Inc. 2 | # Licensed under the Apache License, Version 2.0 (the "License") 3 | 4 | ''' HTTP Errors 5 | 6 | This script ouputs a table of the HTTP total requests count and 7 | HTTP error (>4xxx) count for each service in the `px-sock-shop` namespace. 8 | ''' 9 | 10 | import px 11 | 12 | df = px.DataFrame(table='http_events', start_time='-5m') 13 | 14 | # Add column for HTTP response status errors. 15 | df.error = df.resp_status >= 400 16 | 17 | # Add columns for service, namespace info 18 | df.namespace = df.ctx['namespace'] 19 | df.service = df.ctx['service'] 20 | 21 | # Filter for px-sock-shop namespace only. 22 | df = df[df.namespace == 'px-sock-shop'] 23 | 24 | # Group HTTP events by service, counting errors and total HTTP events. 25 | df = df.groupby(['service']).agg( 26 | error_count=('error', px.sum), 27 | total_requests=('resp_status', px.count) 28 | ) 29 | 30 | px.display(df, "http_table") 31 | -------------------------------------------------------------------------------- /slack-alert-app/python/http_errors.pxl: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pixie Labs, Inc. 2 | # Licensed under the Apache License, Version 2.0 (the "License") 3 | 4 | ''' HTTP Errors 5 | 6 | This script ouputs a table of the HTTP total requests count and 7 | HTTP error (>4xxx) count for each service in the `px-sock-shop` namespace. 8 | ''' 9 | 10 | import px 11 | 12 | df = px.DataFrame(table='http_events', start_time='-5m') 13 | 14 | # Add column for HTTP response status errors. 15 | df.error = df.resp_status >= 400 16 | 17 | # Add columns for service, namespace info 18 | df.namespace = df.ctx['namespace'] 19 | df.service = df.ctx['service'] 20 | 21 | # Filter for px-sock-shop namespace only. 22 | df = df[df.namespace == 'px-sock-shop'] 23 | 24 | # Group HTTP events by service, counting errors and total HTTP events. 25 | df = df.groupby(['service']).agg( 26 | error_count=('error', px.sum), 27 | total_requests=('resp_status', px.count) 28 | ) 29 | 30 | px.display(df, "http_table") 31 | -------------------------------------------------------------------------------- /slack-alert-app/python/requirements.txt: -------------------------------------------------------------------------------- 1 | pxapi==0.4.1 2 | schedule==0.6.0 3 | slack==0.0.2 4 | slackclient==2.9.3 5 | -------------------------------------------------------------------------------- /sql-injection-demo/dvwa-k8s/web_deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: dvwa-pixie-demo 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: dvwa 10 | template: 11 | metadata: 12 | labels: 13 | app: dvwa 14 | spec: 15 | containers: 16 | - name: dvwa 17 | image: vulnerables/web-dvwa 18 | ports: 19 | - name: http 20 | containerPort: 80 21 | 22 | -------------------------------------------------------------------------------- /sql-injection-demo/slackbot/requirements.txt: -------------------------------------------------------------------------------- 1 | pxapi==0.4.1 2 | schedule==0.6.0 3 | slack==0.0.2 4 | slackclient==2.9.3 5 | --------------------------------------------------------------------------------