└── ch6 ├── kubernetes ├── README.md ├── logs │ ├── cluster.sh │ ├── collector.yaml │ └── kind.yaml └── metrics │ ├── cluster.sh │ ├── collector.yaml │ └── kind.yaml └── transforms ├── collector-config.yaml ├── compose.yml ├── html └── index.html ├── log ├── access.log └── error.log └── nginx.conf /ch6/kubernetes/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Metrics 2 | 3 | Each directory contains a script to create a single-node Kubernetes cluster 4 | using KIND, as well as an associated deployment for the OpenTelemetry Collector. 5 | 6 | ## Prerequisites 7 | 8 | - KIND v0.20.0+ 9 | - jq 10 | - kubectl 11 | 12 | ## Usage 13 | 14 | In each directory, you can run `./cluster.sh` to create the cluster. After it's 15 | up, run `kubectl apply -f collector.yaml` to deploy. 16 | 17 | In a web browser, navigate to `https://localhost:30000` to view metrics. 18 | 19 | ## Metrics Available By Receiver Type 20 | 21 | `k8s_cluster` 22 | k8s_container_cpu_limit{} 23 | k8s_container_cpu_request{} 24 | k8s_container_memory_limit{} 25 | k8s_container_memory_request{} 26 | k8s_container_ready{} 27 | k8s_container_restarts{} 28 | k8s_daemonset_current_scheduled_nodes{} 29 | k8s_daemonset_desired_scheduled_nodes{} 30 | k8s_daemonset_misscheduled_nodes{} 31 | k8s_daemonset_ready_nodes{} 32 | k8s_deployment_available{} 33 | k8s_deployment_desired{} 34 | k8s_namespace_phase{} 35 | k8s_node_condition_ready{} 36 | k8s_pod_phase{} 37 | k8s_replicaset_available{} 38 | k8s_replicaset_desired{} 39 | k8s_statefulset_current_pods{} 40 | k8s_statefulset_desired_pods{} 41 | k8s_statefulset_ready_pods{} 42 | k8s_statefulset_updated_pods{} 43 | 44 | `kubeletstats` 45 | container_cpu_time{} 46 | container_cpu_utilization{} 47 | container_filesystem_available{} 48 | container_filesystem_capacity{} 49 | container_filesystem_usage{} 50 | container_memory_working_set{} 51 | k8s_node_cpu_time{} 52 | k8s_node_cpu_utilization{} 53 | k8s_node_filesystem_available{} 54 | k8s_node_filesystem_capacity{} 55 | k8s_node_filesystem_usage{} 56 | k8s_node_memory_available{} 57 | k8s_node_memory_major_page_faults{} 58 | k8s_node_memory_page_faults{} 59 | k8s_node_memory_rss{} 60 | k8s_node_memory_usage{} 61 | k8s_node_memory_working_set{} 62 | k8s_node_network_errors{} 63 | k8s_node_network_io{} 64 | k8s_pod_cpu_time{} 65 | k8s_pod_filesystem_available{} 66 | k8s_pod_filesystem_capacity{} 67 | k8s_pod_filesystem_usage{} 68 | k8s_pod_memory_available{} 69 | k8s_pod_memory_major_page_faults{} 70 | k8s_pod_memory_page_faults{} 71 | k8s_pod_memory_rss{} 72 | k8s_pod_memory_usage{} 73 | k8s_pod_memory_working_set{} 74 | k8s_pod_network_errors{} 75 | k8s_pod_network_io{} 76 | -------------------------------------------------------------------------------- /ch6/kubernetes/logs/cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to check if kind is installed and the version is v0.20.0 or greater 4 | function check_kind { 5 | if command -v kind >/dev/null 2>&1; then 6 | version=$(kind version | cut -d " " -f 2 | tr -d 'v') # Extracts the version number and remove 'v' 7 | required_version="0.20.0" 8 | if (( $(echo "$version $required_version" | awk '{print ($1 >= $2)}') )); then 9 | echo "Kind version $version is installed. Proceeding..." 10 | return 0 11 | else 12 | echo "Kind version is less than required ($required_version). Please update Kind and try again." 13 | return 1 14 | fi 15 | else 16 | echo "Kind is not installed. Please install Kind and try again." 17 | return 1 18 | fi 19 | } 20 | 21 | # Function to check if kubectl is installed 22 | function check_kubectl { 23 | if command -v kubectl >/dev/null 2>&1; then 24 | echo "Kubectl is installed. Proceeding..." 25 | return 0 26 | else 27 | echo "Kubectl is not installed. Please install Kubectl and try again." 28 | return 1 29 | fi 30 | } 31 | 32 | # Function to create a single node cluster 33 | function create_cluster { 34 | # Use the default cluster name (kind) and node name (kind-control-plane) 35 | kind create cluster --config kind.yaml 36 | } 37 | 38 | # Function to install cert-manager 39 | function install_cert_manager { 40 | kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml 41 | echo "Cert-manager applied. Waiting for the deployment to be ready..." 42 | 43 | # Wait for the cert-manager deployment to be ready 44 | kubectl wait --for=condition=available --timeout=600s deployment/cert-manager -n cert-manager 45 | kubectl wait --for=condition=available --timeout=600s deployment/cert-manager-cainjector -n cert-manager 46 | kubectl wait --for=condition=available --timeout=600s deployment/cert-manager-webhook -n cert-manager 47 | echo "Cert-manager deployment is ready." 48 | } 49 | 50 | function install_operator { 51 | kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml 52 | } 53 | 54 | function install_prometheus { 55 | LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name) 56 | curl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f - 57 | } 58 | 59 | # Function to delete the kind cluster 60 | function delete_cluster { 61 | kind delete cluster --name kind 62 | echo "Kind cluster deleted." 63 | } 64 | 65 | # Main script execution 66 | check_kind 67 | check_kubectl 68 | if [ $? -eq 0 ]; then 69 | if [ "$1" == "--delete" ]; then 70 | delete_cluster 71 | else 72 | create_cluster 73 | install_cert_manager 74 | install_operator 75 | install_prometheus 76 | fi 77 | fi -------------------------------------------------------------------------------- /ch6/kubernetes/logs/collector.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app: collector 6 | name: collector 7 | --- 8 | apiVersion: v1 9 | kind: ServiceAccount 10 | metadata: 11 | name: prometheus 12 | --- 13 | apiVersion: rbac.authorization.k8s.io/v1 14 | kind: ClusterRole 15 | metadata: 16 | name: collector 17 | labels: 18 | app: collector 19 | rules: 20 | - nonResourceURLs: 21 | - /metrics 22 | verbs: 23 | - get 24 | - apiGroups: 25 | - "" 26 | resources: 27 | - events 28 | - namespaces 29 | - namespaces/status 30 | - nodes 31 | - nodes/spec 32 | - nodes/stats 33 | - pods 34 | - pods/status 35 | - replicationcontrollers 36 | - replicationcontrollers/status 37 | - resourcequotas 38 | - services 39 | verbs: 40 | - get 41 | - list 42 | - watch 43 | - apiGroups: 44 | - apps 45 | resources: 46 | - daemonsets 47 | - deployments 48 | - replicasets 49 | - statefulsets 50 | verbs: 51 | - get 52 | - list 53 | - watch 54 | - apiGroups: 55 | - extensions 56 | resources: 57 | - daemonsets 58 | - deployments 59 | - replicasets 60 | verbs: 61 | - get 62 | - list 63 | - watch 64 | - apiGroups: 65 | - batch 66 | resources: 67 | - jobs 68 | - cronjobs 69 | verbs: 70 | - get 71 | - list 72 | - watch 73 | - apiGroups: 74 | - autoscaling 75 | resources: 76 | - horizontalpodautoscalers 77 | verbs: 78 | - get 79 | - list 80 | - watch 81 | --- 82 | apiVersion: rbac.authorization.k8s.io/v1 83 | kind: ClusterRole 84 | metadata: 85 | name: prometheus 86 | rules: 87 | - apiGroups: [""] 88 | resources: 89 | - nodes 90 | - nodes/metrics 91 | - services 92 | - endpoints 93 | - pods 94 | verbs: ["get", "list", "watch"] 95 | - apiGroups: [""] 96 | resources: 97 | - configmaps 98 | verbs: ["get"] 99 | - apiGroups: 100 | - networking.k8s.io 101 | resources: 102 | - ingresses 103 | verbs: ["get", "list", "watch"] 104 | - nonResourceURLs: ["/metrics"] 105 | verbs: ["get"] 106 | --- 107 | apiVersion: rbac.authorization.k8s.io/v1 108 | kind: ClusterRoleBinding 109 | metadata: 110 | name: collector-crb 111 | labels: 112 | app: collector-crb 113 | roleRef: 114 | apiGroup: rbac.authorization.k8s.io 115 | kind: ClusterRole 116 | name: collector 117 | subjects: 118 | - kind: ServiceAccount 119 | name: collector 120 | namespace: default 121 | --- 122 | apiVersion: rbac.authorization.k8s.io/v1 123 | kind: ClusterRoleBinding 124 | metadata: 125 | name: prometheus 126 | roleRef: 127 | apiGroup: rbac.authorization.k8s.io 128 | kind: ClusterRole 129 | name: prometheus 130 | subjects: 131 | - kind: ServiceAccount 132 | name: prometheus 133 | namespace: default 134 | --- 135 | apiVersion: monitoring.coreos.com/v1 136 | kind: ServiceMonitor 137 | metadata: 138 | name: collector 139 | labels: 140 | app: collector 141 | spec: 142 | selector: 143 | matchLabels: 144 | app: collector 145 | endpoints: 146 | - port: metrics 147 | --- 148 | apiVersion: monitoring.coreos.com/v1 149 | kind: Prometheus 150 | metadata: 151 | name: prometheus 152 | spec: 153 | serviceAccountName: prometheus 154 | serviceMonitorSelector: 155 | matchLabels: 156 | app: collector 157 | enableAdminAPI: false 158 | --- 159 | apiVersion: v1 160 | kind: Service 161 | metadata: 162 | name: prometheus 163 | spec: 164 | type: NodePort 165 | ports: 166 | - name: web 167 | nodePort: 30000 168 | port: 9090 169 | protocol: TCP 170 | targetPort: web 171 | selector: 172 | prometheus: prometheus 173 | --- 174 | apiVersion: opentelemetry.io/v1alpha1 175 | kind: OpenTelemetryCollector 176 | metadata: 177 | name: collector 178 | labels: 179 | app: collector 180 | spec: 181 | image: otel/opentelemetry-collector-contrib:0.81.0 182 | serviceAccount: collector 183 | ports: 184 | - name: metrics 185 | port: 55681 186 | protocol: TCP 187 | env: 188 | - name: K8S_NODE_NAME 189 | valueFrom: 190 | fieldRef: 191 | fieldPath: spec.nodeName 192 | config: | 193 | receivers: 194 | k8s_cluster: 195 | collection_interval: 10s 196 | kubeletstats: 197 | collection_interval: 10s 198 | auth_type: "serviceAccount" 199 | endpoint: "https://${env:K8S_NODE_NAME}:10250" 200 | insecure_skip_verify: true 201 | exporters: 202 | logging: 203 | prometheus: 204 | endpoint: 0.0.0.0:55681 205 | service: 206 | pipelines: 207 | metrics: 208 | receivers: [kubeletstats] 209 | processors: [] 210 | exporters: [logging, prometheus] 211 | -------------------------------------------------------------------------------- /ch6/kubernetes/logs/kind.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kind.x-k8s.io/v1alpha4 2 | kind: Cluster 3 | featureGates: 4 | PodAndContainerStatsFromCRI: true 5 | nodes: 6 | - role: control-plane 7 | extraPortMappings: 8 | - containerPort: 30000 9 | hostPort: 30000 10 | listenAddress: "0.0.0.0" -------------------------------------------------------------------------------- /ch6/kubernetes/metrics/cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to check if kind is installed and the version is v0.20.0 or greater 4 | function check_kind { 5 | if command -v kind >/dev/null 2>&1; then 6 | version=$(kind version | cut -d " " -f 2 | tr -d 'v') # Extracts the version number and remove 'v' 7 | required_version="0.20.0" 8 | if (( $(echo "$version $required_version" | awk '{print ($1 >= $2)}') )); then 9 | echo "Kind version $version is installed. Proceeding..." 10 | return 0 11 | else 12 | echo "Kind version is less than required ($required_version). Please update Kind and try again." 13 | return 1 14 | fi 15 | else 16 | echo "Kind is not installed. Please install Kind and try again." 17 | return 1 18 | fi 19 | } 20 | 21 | # Function to check if kubectl is installed 22 | function check_kubectl { 23 | if command -v kubectl >/dev/null 2>&1; then 24 | echo "Kubectl is installed. Proceeding..." 25 | return 0 26 | else 27 | echo "Kubectl is not installed. Please install Kubectl and try again." 28 | return 1 29 | fi 30 | } 31 | 32 | # Function to create a single node cluster 33 | function create_cluster { 34 | # Use the default cluster name (kind) and node name (kind-control-plane) 35 | kind create cluster --config kind.yaml 36 | } 37 | 38 | # Function to install cert-manager 39 | function install_cert_manager { 40 | kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml 41 | echo "Cert-manager applied. Waiting for the deployment to be ready..." 42 | 43 | # Wait for the cert-manager deployment to be ready 44 | kubectl wait --for=condition=available --timeout=600s deployment/cert-manager -n cert-manager 45 | kubectl wait --for=condition=available --timeout=600s deployment/cert-manager-cainjector -n cert-manager 46 | kubectl wait --for=condition=available --timeout=600s deployment/cert-manager-webhook -n cert-manager 47 | echo "Cert-manager deployment is ready." 48 | } 49 | 50 | function install_operator { 51 | kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml 52 | } 53 | 54 | function install_prometheus { 55 | LATEST=$(curl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name) 56 | curl -sL https://github.com/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f - 57 | } 58 | 59 | # Function to delete the kind cluster 60 | function delete_cluster { 61 | kind delete cluster --name kind 62 | echo "Kind cluster deleted." 63 | } 64 | 65 | # Main script execution 66 | check_kind 67 | check_kubectl 68 | if [ $? -eq 0 ]; then 69 | if [ "$1" == "--delete" ]; then 70 | delete_cluster 71 | else 72 | create_cluster 73 | install_cert_manager 74 | install_operator 75 | install_prometheus 76 | fi 77 | fi -------------------------------------------------------------------------------- /ch6/kubernetes/metrics/collector.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app: collector 6 | name: collector 7 | --- 8 | apiVersion: v1 9 | kind: ServiceAccount 10 | metadata: 11 | name: prometheus 12 | --- 13 | apiVersion: rbac.authorization.k8s.io/v1 14 | kind: ClusterRole 15 | metadata: 16 | name: collector 17 | labels: 18 | app: collector 19 | rules: 20 | - nonResourceURLs: 21 | - /metrics 22 | verbs: 23 | - get 24 | - apiGroups: 25 | - "" 26 | resources: 27 | - events 28 | - namespaces 29 | - namespaces/status 30 | - nodes 31 | - nodes/spec 32 | - nodes/stats 33 | - pods 34 | - pods/status 35 | - replicationcontrollers 36 | - replicationcontrollers/status 37 | - resourcequotas 38 | - services 39 | verbs: 40 | - get 41 | - list 42 | - watch 43 | - apiGroups: 44 | - apps 45 | resources: 46 | - daemonsets 47 | - deployments 48 | - replicasets 49 | - statefulsets 50 | verbs: 51 | - get 52 | - list 53 | - watch 54 | - apiGroups: 55 | - extensions 56 | resources: 57 | - daemonsets 58 | - deployments 59 | - replicasets 60 | verbs: 61 | - get 62 | - list 63 | - watch 64 | - apiGroups: 65 | - batch 66 | resources: 67 | - jobs 68 | - cronjobs 69 | verbs: 70 | - get 71 | - list 72 | - watch 73 | - apiGroups: 74 | - autoscaling 75 | resources: 76 | - horizontalpodautoscalers 77 | verbs: 78 | - get 79 | - list 80 | - watch 81 | --- 82 | apiVersion: rbac.authorization.k8s.io/v1 83 | kind: ClusterRole 84 | metadata: 85 | name: prometheus 86 | rules: 87 | - apiGroups: [""] 88 | resources: 89 | - nodes 90 | - nodes/metrics 91 | - services 92 | - endpoints 93 | - pods 94 | verbs: ["get", "list", "watch"] 95 | - apiGroups: [""] 96 | resources: 97 | - configmaps 98 | verbs: ["get"] 99 | - apiGroups: 100 | - networking.k8s.io 101 | resources: 102 | - ingresses 103 | verbs: ["get", "list", "watch"] 104 | - nonResourceURLs: ["/metrics"] 105 | verbs: ["get"] 106 | --- 107 | apiVersion: rbac.authorization.k8s.io/v1 108 | kind: ClusterRoleBinding 109 | metadata: 110 | name: collector-crb 111 | labels: 112 | app: collector-crb 113 | roleRef: 114 | apiGroup: rbac.authorization.k8s.io 115 | kind: ClusterRole 116 | name: collector 117 | subjects: 118 | - kind: ServiceAccount 119 | name: collector 120 | namespace: default 121 | --- 122 | apiVersion: rbac.authorization.k8s.io/v1 123 | kind: ClusterRoleBinding 124 | metadata: 125 | name: prometheus 126 | roleRef: 127 | apiGroup: rbac.authorization.k8s.io 128 | kind: ClusterRole 129 | name: prometheus 130 | subjects: 131 | - kind: ServiceAccount 132 | name: prometheus 133 | namespace: default 134 | --- 135 | apiVersion: monitoring.coreos.com/v1 136 | kind: ServiceMonitor 137 | metadata: 138 | name: collector 139 | labels: 140 | app: collector 141 | spec: 142 | selector: 143 | matchLabels: 144 | app: collector 145 | endpoints: 146 | - port: metrics 147 | --- 148 | apiVersion: monitoring.coreos.com/v1 149 | kind: Prometheus 150 | metadata: 151 | name: prometheus 152 | spec: 153 | serviceAccountName: prometheus 154 | serviceMonitorSelector: 155 | matchLabels: 156 | app: collector 157 | enableAdminAPI: false 158 | --- 159 | apiVersion: v1 160 | kind: Service 161 | metadata: 162 | name: prometheus 163 | spec: 164 | type: NodePort 165 | ports: 166 | - name: web 167 | nodePort: 30000 168 | port: 9090 169 | protocol: TCP 170 | targetPort: web 171 | selector: 172 | prometheus: prometheus 173 | --- 174 | apiVersion: opentelemetry.io/v1alpha1 175 | kind: OpenTelemetryCollector 176 | metadata: 177 | name: collector 178 | labels: 179 | app: collector 180 | spec: 181 | image: otel/opentelemetry-collector-contrib:0.81.0 182 | serviceAccount: collector 183 | ports: 184 | - name: metrics 185 | port: 55681 186 | protocol: TCP 187 | env: 188 | - name: K8S_NODE_NAME 189 | valueFrom: 190 | fieldRef: 191 | fieldPath: spec.nodeName 192 | config: | 193 | receivers: 194 | k8s_cluster: 195 | collection_interval: 10s 196 | kubeletstats: 197 | collection_interval: 10s 198 | auth_type: "serviceAccount" 199 | endpoint: "https://${env:K8S_NODE_NAME}:10250" 200 | insecure_skip_verify: true 201 | exporters: 202 | logging: 203 | prometheus: 204 | endpoint: 0.0.0.0:55681 205 | service: 206 | pipelines: 207 | metrics: 208 | receivers: [kubeletstats] 209 | processors: [] 210 | exporters: [logging, prometheus] 211 | -------------------------------------------------------------------------------- /ch6/kubernetes/metrics/kind.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kind.x-k8s.io/v1alpha4 2 | kind: Cluster 3 | featureGates: 4 | PodAndContainerStatsFromCRI: true 5 | nodes: 6 | - role: control-plane 7 | extraPortMappings: 8 | - containerPort: 30000 9 | hostPort: 30000 10 | listenAddress: "0.0.0.0" -------------------------------------------------------------------------------- /ch6/transforms/collector-config.yaml: -------------------------------------------------------------------------------- 1 | receivers: 2 | nginx: 3 | endpoint: "http://web:80/status" 4 | collection_interval: 10s 5 | filelog: 6 | include: ["/var/log/nginx/access.log"] 7 | operators: 8 | - type: regex_parser 9 | regex: (?P((?:[0-9]{1,3}\.){3}[0-9]{1,3})) (?P\S+) (?P\S+) \[(?P[\w:\/]+\s[+|-]\d{4})\] \"(?P\S+)\s?(?P\S+)?\s?(?P\S+)?\" (?P\d{3}|-) (?P\d+|-)\s?\"?(?P[^\"]*)\"?\s\"?(?P[^\"]*)\"\s\"?(?P[^\"]*) 10 | timestamp: 11 | parse_from: attributes.time_local 12 | layout: '%d/%b/%Y:%H:%M:%S.%f %z' 13 | 14 | exporters: 15 | logging: 16 | loglevel: debug 17 | 18 | processors: 19 | transform: 20 | error_mode: ignore 21 | log_statements: 22 | - context: log 23 | statements: 24 | - set(attributes["http.request.body.size"], attributes["body_bytes_sent"]) 25 | - delete_key(attributes, "body_bytes_sent") 26 | - set(attributes["http.request.method"], attributes["request"]) 27 | - delete_key(attributes, "request") 28 | 29 | service: 30 | pipelines: 31 | metrics: 32 | receivers: [nginx] 33 | exporters: [logging] 34 | logs: 35 | receivers: [filelog] 36 | processors: [transform] 37 | exporters: [logging] 38 | -------------------------------------------------------------------------------- /ch6/transforms/compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | services: 3 | web: 4 | image: nginx:latest 5 | ports: 6 | - "8080:80" 7 | volumes: 8 | - ./nginx.conf:/etc/nginx/nginx.conf 9 | - ./log:/var/log/nginx 10 | - ./html:/usr/share/nginx/html 11 | collector: 12 | image: otel/opentelemetry-collector-contrib:0.81.0 13 | command: ["--config=/etc/otel/collector-config.yaml"] 14 | volumes: 15 | - ./collector-config.yaml:/etc/otel/collector-config.yaml 16 | - ./log:/var/log/nginx -------------------------------------------------------------------------------- /ch6/transforms/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello, OpenTelemetry 5 | 6 | 7 |

Hello, OpenTelemetry

8 | 9 | 10 | -------------------------------------------------------------------------------- /ch6/transforms/log/access.log: -------------------------------------------------------------------------------- 1 | 172.18.0.2 - - [27/Jul/2023:14:49:43 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 2 | 172.18.0.2 - - [27/Jul/2023:14:49:43 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 3 | 172.18.0.2 - - [27/Jul/2023:14:49:53 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 4 | 172.18.0.2 - - [27/Jul/2023:14:50:03 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 5 | 172.18.0.2 - - [27/Jul/2023:14:50:13 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 6 | 172.18.0.2 - - [27/Jul/2023:14:50:23 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 7 | 172.18.0.2 - - [27/Jul/2023:14:50:33 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 8 | 172.18.0.2 - - [27/Jul/2023:14:50:43 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 9 | 172.18.0.2 - - [27/Jul/2023:14:50:53 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 10 | 172.18.0.2 - - [27/Jul/2023:14:51:03 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 11 | 172.18.0.2 - - [27/Jul/2023:14:51:13 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 12 | 172.18.0.2 - - [27/Jul/2023:14:51:23 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 13 | 172.18.0.2 - - [27/Jul/2023:14:51:33 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 14 | 172.18.0.2 - - [27/Jul/2023:14:51:43 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 15 | 172.18.0.2 - - [27/Jul/2023:14:51:53 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 16 | 172.18.0.2 - - [27/Jul/2023:14:52:03 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 17 | 172.18.0.2 - - [27/Jul/2023:14:52:13 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 18 | 172.18.0.2 - - [27/Jul/2023:14:52:23 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 19 | 172.18.0.2 - - [27/Jul/2023:14:55:38 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 20 | 172.18.0.2 - - [27/Jul/2023:14:55:38 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 21 | 172.18.0.2 - - [27/Jul/2023:14:55:48 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 22 | 172.18.0.2 - - [27/Jul/2023:15:02:54 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 23 | 172.18.0.2 - - [27/Jul/2023:15:02:54 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 24 | 172.18.0.2 - - [27/Jul/2023:15:03:04 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 25 | 172.18.0.2 - - [27/Jul/2023:15:03:14 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 26 | 172.18.0.2 - - [27/Jul/2023:15:03:24 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 27 | 172.18.0.2 - - [27/Jul/2023:15:03:34 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 28 | 172.18.0.2 - - [27/Jul/2023:15:03:43 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 29 | 172.18.0.2 - - [27/Jul/2023:15:03:43 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 30 | 172.18.0.2 - - [27/Jul/2023:15:03:53 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 31 | 172.18.0.2 - - [27/Jul/2023:15:04:03 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 32 | 172.18.0.2 - - [27/Jul/2023:15:04:13 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 33 | 172.18.0.2 - - [27/Jul/2023:15:04:23 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 34 | 172.18.0.2 - - [27/Jul/2023:15:04:33 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 35 | 172.18.0.2 - - [27/Jul/2023:15:04:43 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 36 | 172.18.0.2 - - [27/Jul/2023:15:04:53 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 37 | 172.18.0.2 - - [27/Jul/2023:15:05:03 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 38 | 172.18.0.2 - - [27/Jul/2023:15:05:13 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 39 | 172.18.0.2 - - [27/Jul/2023:15:05:23 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 40 | 172.18.0.2 - - [27/Jul/2023:15:05:33 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 41 | 172.18.0.2 - - [27/Jul/2023:15:05:43 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 42 | 172.18.0.2 - - [27/Jul/2023:15:05:53 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 43 | 172.18.0.2 - - [27/Jul/2023:15:06:03 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 44 | 172.18.0.2 - - [27/Jul/2023:15:06:13 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 45 | 172.18.0.2 - - [27/Jul/2023:15:06:23 +0000] "GET /status HTTP/1.1" 200 98 "-" "Go-http-client/1.1" 46 | 172.18.0.2 - - [27/Jul/2023:15:11:48 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 47 | 172.18.0.2 - - [27/Jul/2023:15:11:48 +0000] "GET /status HTTP/1.1" 200 97 "-" "Go-http-client/1.1" 48 | -------------------------------------------------------------------------------- /ch6/transforms/log/error.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learning-opentelemetry-oreilly/examples/c0176d38d43eadda02a0bf4bcee23e8487dd0654/ch6/transforms/log/error.log -------------------------------------------------------------------------------- /ch6/transforms/nginx.conf: -------------------------------------------------------------------------------- 1 | # /etc/nginx/nginx.conf 2 | 3 | user nginx; 4 | worker_processes auto; 5 | error_log /var/log/nginx/error.log; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | access_log /var/log/nginx/access.log combined; 13 | 14 | include /etc/nginx/mime.types; 15 | default_type application/octet-stream; 16 | sendfile on; 17 | keepalive_timeout 65; 18 | 19 | server { 20 | listen 80 default_server; 21 | server_name _; 22 | root /usr/share/nginx/html; 23 | index index.html; 24 | 25 | location = /status { 26 | stub_status; 27 | } 28 | 29 | location / { 30 | try_files $uri $uri/ =404; 31 | } 32 | } 33 | } 34 | --------------------------------------------------------------------------------