|
| 1 | +from typing import Iterator |
| 2 | +from contextlib import closing |
| 3 | +from django.db import connections |
| 4 | + |
| 5 | + |
| 6 | +query_network_flow_sql_tpl = """ |
| 7 | +SELECT |
| 8 | + namespace, |
| 9 | + pod_name, |
| 10 | + last(rx_bytes, time) - first(rx_bytes, time) as rx_bytes, |
| 11 | + last(tx_bytes, time) - first(tx_bytes, time) as tx_bytes |
| 12 | +FROM kubernetes_pod_network |
| 13 | +LEFT OUTER JOIN kubernetes_pod_network_tag |
| 14 | +ON kubernetes_pod_network.tag_id = kubernetes_pod_network_tag.tag_id |
| 15 | +WHERE |
| 16 | + namespace in ({namespace_range}) |
| 17 | + AND |
| 18 | + time < to_timestamp({start}) |
| 19 | + AND |
| 20 | + time > to_timestamp({stop}) |
| 21 | +GROUP by namespace, pod_name |
| 22 | +""" |
| 23 | + |
| 24 | + |
| 25 | +query_container_count_sql_tpl = """ |
| 26 | +SELECT |
| 27 | + count(1) |
| 28 | +FROM ( |
| 29 | + SELECT |
| 30 | + namespace, |
| 31 | + pod_name, |
| 32 | + container_name |
| 33 | + FROM kubernetes_pod_container |
| 34 | + LEFT OUTER JOIN kubernetes_pod_container_tag |
| 35 | + ON kubernetes_pod_container.tag_id = kubernetes_pod_container_tag.tag_id |
| 36 | + WHERE |
| 37 | + namespace='{namespace}' |
| 38 | + container_name='{container_name}' |
| 39 | + AND time < to_timestamp({start}) |
| 40 | + AND time > to_timestamp({stop}) |
| 41 | + GROUP BY namespace, pod_name, container_name, kubernetes_pod_container.tag_id |
| 42 | +) AS container |
| 43 | +GROUP BY namespace, container_name |
| 44 | +""" |
| 45 | + |
| 46 | + |
| 47 | +query_cpu_usage_sql_tpl = """ |
| 48 | +SELECT |
| 49 | + namespace, |
| 50 | + pod_name, |
| 51 | + container_name, |
| 52 | + round(EXTRACT(EPOCH FROM time_bucket('{every}', time))) as timestamp, |
| 53 | + max(cpu_usage_nanocores), |
| 54 | + round(avg(cpu_usage_nanocores)) |
| 55 | +FROM kubernetes_pod_container |
| 56 | +LEFT OUTER JOIN kubernetes_pod_container_tag |
| 57 | +ON kubernetes_pod_container.tag_id = kubernetes_pod_container_tag.tag_id |
| 58 | +WHERE |
| 59 | + namespace='{namespace}' |
| 60 | + container_name='{container_name}' |
| 61 | + AND time < to_timestamp({start}) |
| 62 | + AND time > to_timestamp({stop}) |
| 63 | +GROUP BY namespace, pod_name, container_name, timestamp |
| 64 | +""" |
| 65 | + |
| 66 | + |
| 67 | +query_memory_usage_sql_tpl = """ |
| 68 | +SELECT |
| 69 | + namespace, |
| 70 | + pod_name, |
| 71 | + container_name, |
| 72 | + round(EXTRACT(EPOCH FROM time_bucket('{every}', time))) as timestamp, |
| 73 | + max(memory_usage_bytes) as max, |
| 74 | + round(avg(memory_usage_bytes)) as avg |
| 75 | +FROM kubernetes_pod_container |
| 76 | +LEFT OUTER JOIN kubernetes_pod_container_tag |
| 77 | +ON kubernetes_pod_container.tag_id = kubernetes_pod_container_tag.tag_id |
| 78 | +WHERE |
| 79 | + namespace='{namespace}' |
| 80 | + container_name='{container_name}' |
| 81 | + AND time < to_timestamp({start}) |
| 82 | + AND time > to_timestamp({stop}) |
| 83 | +GROUP BY namespace, pod_name, container_name, timestamp |
| 84 | +""" |
| 85 | + |
| 86 | + |
| 87 | +query_network_usage_sql_tpl = """ |
| 88 | +SELECT |
| 89 | + namespace, |
| 90 | + pod_name, |
| 91 | + round(EXTRACT(EPOCH FROM time_bucket('{every}', time))) as timestamp, |
| 92 | + last(rx_bytes, time) - first(rx_bytes, time) as rx_bytes, |
| 93 | + last(tx_bytes, time) - first(tx_bytes, time) as tx_bytes |
| 94 | +FROM kubernetes_pod_network |
| 95 | +LEFT OUTER JOIN kubernetes_pod_network_tag |
| 96 | +ON kubernetes_pod_network.tag_id = kubernetes_pod_network_tag.tag_id |
| 97 | +WHERE |
| 98 | + namespace='{namespace}' |
| 99 | + pod_name like '{pod_name_prefix}%' |
| 100 | + AND |
| 101 | + time < to_timestamp({start}) |
| 102 | + AND |
| 103 | + time > to_timestamp({stop}) |
| 104 | +GROUP by namespace, pod_name, timestamp |
| 105 | +""" |
| 106 | + |
| 107 | + |
| 108 | +def query_network_flow(namespaces: Iterator[str], |
| 109 | + start: int, stop: int) -> Iterator[tuple[str, str, int, int]]: |
| 110 | + with closing(connections['monitor'].cursor()) as cursor: |
| 111 | + namespace_range = ', '.join([f"'{namespace}'" for namespace in namespaces]) |
| 112 | + sql = query_network_flow_sql_tpl.format( |
| 113 | + namespace_range=namespace_range, start=start, stop=stop) |
| 114 | + cursor.execute(sql) |
| 115 | + yield from cursor |
| 116 | + |
| 117 | + |
| 118 | +def query_container_count(namespace: str, container_type: str, start: int, stop: int) -> int: |
| 119 | + with closing(connections['monitor'].cursor()) as cursor: |
| 120 | + container_name = "%s-%s" % (namespace, container_type) |
| 121 | + sql = query_network_flow_sql_tpl.format( |
| 122 | + namespace=namespace, container_name=container_name, start=start, stop=stop) |
| 123 | + cursor.execute(sql) |
| 124 | + row = cursor.fetchone() |
| 125 | + return row[0] if row else 0 |
| 126 | + |
| 127 | + |
| 128 | +def query_cpu_usage(namespace: str, container_type: str, |
| 129 | + start: int, stop: int, every: str |
| 130 | + ) -> Iterator[tuple[str, str, str, int, int, int]]: |
| 131 | + with closing(connections['monitor'].cursor()) as cursor: |
| 132 | + container_name = "%s-%s" % (namespace, container_type) |
| 133 | + sql = query_cpu_usage_sql_tpl.format( |
| 134 | + namespace=namespace, container_name=container_name, |
| 135 | + start=start, stop=stop, every=every) |
| 136 | + cursor.execute(sql) |
| 137 | + yield from cursor |
| 138 | + |
| 139 | + |
| 140 | +def query_memory_usage(namespace: str, container_type: str, |
| 141 | + start: int, stop: int, every: str |
| 142 | + ) -> Iterator[tuple[str, str, str, int, int, int]]: |
| 143 | + with closing(connections['monitor'].cursor()) as cursor: |
| 144 | + container_name = "%s-%s" % (namespace, container_type) |
| 145 | + sql = query_memory_usage_sql_tpl.format( |
| 146 | + namespace=namespace, container_name=container_name, |
| 147 | + start=start, stop=stop, every=every) |
| 148 | + cursor.execute(sql) |
| 149 | + yield from cursor |
| 150 | + |
| 151 | + |
| 152 | +def query_network_usage(namespace: str, container_type: str, |
| 153 | + start: int, stop: int, every: str |
| 154 | + ) -> Iterator[tuple[str, str, int, int, int]]: |
| 155 | + with closing(connections['monitor'].cursor()) as cursor: |
| 156 | + pod_name_prefix = "%s-%s" % (namespace, container_type) |
| 157 | + sql = query_network_usage_sql_tpl.format( |
| 158 | + namespace=namespace, pod_name_prefix=pod_name_prefix, |
| 159 | + start=start, stop=stop, every=every) |
| 160 | + cursor.execute(sql) |
| 161 | + yield from cursor |
0 commit comments