at 25.11-pre 5.1 kB view raw
1import ../make-test-python.nix ( 2 { lib, pkgs, ... }: 3 4 { 5 name = "vector-nginx-clickhouse"; 6 meta.maintainers = [ pkgs.lib.maintainers.happysalada ]; 7 8 nodes = { 9 clickhouse = 10 { config, pkgs, ... }: 11 { 12 virtualisation.memorySize = 4096; 13 14 # Clickhouse module can't listen on a non-loopback IP. 15 networking.firewall.allowedTCPPorts = [ 6000 ]; 16 services.clickhouse.enable = true; 17 18 # Exercise Vector sink->source for now. 19 services.vector = { 20 enable = true; 21 22 settings = { 23 sources = { 24 vector_source = { 25 type = "vector"; 26 address = "[::]:6000"; 27 }; 28 }; 29 30 sinks = { 31 clickhouse = { 32 type = "clickhouse"; 33 inputs = [ "vector_source" ]; 34 endpoint = "http://localhost:8123"; 35 database = "nginxdb"; 36 table = "access_logs"; 37 skip_unknown_fields = true; 38 }; 39 }; 40 }; 41 }; 42 }; 43 44 nginx = 45 { config, pkgs, ... }: 46 { 47 services.nginx = { 48 enable = true; 49 virtualHosts.localhost = { }; 50 }; 51 52 services.vector = { 53 enable = true; 54 55 settings = { 56 sources = { 57 nginx_logs = { 58 type = "file"; 59 include = [ "/var/log/nginx/access.log" ]; 60 read_from = "end"; 61 }; 62 }; 63 64 sinks = { 65 vector_sink = { 66 type = "vector"; 67 inputs = [ "nginx_logs" ]; 68 address = "clickhouse:6000"; 69 }; 70 }; 71 }; 72 }; 73 74 systemd.services.vector.serviceConfig = { 75 SupplementaryGroups = [ "nginx" ]; 76 }; 77 }; 78 }; 79 80 testScript = 81 let 82 # work around quote/substitution complexity by Nix, Perl, bash and SQL. 83 databaseDDL = pkgs.writeText "database.sql" "CREATE DATABASE IF NOT EXISTS nginxdb"; 84 85 tableDDL = pkgs.writeText "table.sql" '' 86 CREATE TABLE IF NOT EXISTS nginxdb.access_logs ( 87 message String 88 ) 89 ENGINE = MergeTree() 90 ORDER BY tuple() 91 ''; 92 93 # Graciously taken from https://clickhouse.com/docs/en/integrations/vector 94 tableView = pkgs.writeText "table-view.sql" '' 95 CREATE MATERIALIZED VIEW nginxdb.access_logs_view 96 ( 97 RemoteAddr String, 98 Client String, 99 RemoteUser String, 100 TimeLocal DateTime, 101 RequestMethod String, 102 Request String, 103 HttpVersion String, 104 Status Int32, 105 BytesSent Int64, 106 UserAgent String 107 ) 108 ENGINE = MergeTree() 109 ORDER BY RemoteAddr 110 POPULATE AS 111 WITH 112 splitByWhitespace(message) as split, 113 splitByRegexp('\S \d+ "([^"]*)"', message) as referer 114 SELECT 115 split[1] AS RemoteAddr, 116 split[2] AS Client, 117 split[3] AS RemoteUser, 118 parseDateTimeBestEffort(replaceOne(trim(LEADING '[' FROM split[4]), ':', ' ')) AS TimeLocal, 119 trim(LEADING '"' FROM split[6]) AS RequestMethod, 120 split[7] AS Request, 121 trim(TRAILING '"' FROM split[8]) AS HttpVersion, 122 split[9] AS Status, 123 split[10] AS BytesSent, 124 trim(BOTH '"' from referer[2]) AS UserAgent 125 FROM 126 (SELECT message FROM nginxdb.access_logs) 127 ''; 128 129 selectQuery = pkgs.writeText "select.sql" "SELECT * from nginxdb.access_logs_view"; 130 in 131 '' 132 clickhouse.wait_for_unit("clickhouse") 133 clickhouse.wait_for_open_port(8123) 134 135 clickhouse.wait_until_succeeds( 136 "journalctl -o cat -u clickhouse.service | grep 'Started ClickHouse server'" 137 ) 138 139 clickhouse.wait_for_unit("vector") 140 clickhouse.wait_for_open_port(6000) 141 142 clickhouse.succeed( 143 "cat ${databaseDDL} | clickhouse-client" 144 ) 145 146 clickhouse.succeed( 147 "cat ${tableDDL} | clickhouse-client" 148 ) 149 150 clickhouse.succeed( 151 "cat ${tableView} | clickhouse-client" 152 ) 153 154 nginx.wait_for_unit("nginx") 155 nginx.wait_for_open_port(80) 156 nginx.wait_for_unit("vector") 157 nginx.wait_until_succeeds( 158 "journalctl -o cat -u vector.service | grep 'Starting file server'" 159 ) 160 161 nginx.succeed("curl http://localhost/") 162 nginx.succeed("curl http://localhost/") 163 164 nginx.wait_for_file("/var/log/nginx/access.log") 165 nginx.wait_until_succeeds( 166 "journalctl -o cat -u vector.service | grep 'Found new file to watch. file=/var/log/nginx/access.log'" 167 ) 168 169 clickhouse.wait_until_succeeds( 170 "cat ${selectQuery} | clickhouse-client | grep 'curl'" 171 ) 172 ''; 173 } 174)