A shiny app to explore nginx access logs and geolocate the connections
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
1.4KB

  1. library(tidyverse)
  2. library(RSQLite)
  3. library(ipapi)
  4. library(leaflet)
  5. dbConnect(SQLite(), "access.db") -> db
  6. read_delim("access.log", delim = " ", col_names = c("ip", "null1", "user", "timestamp", "zone", "req", "status", "size", "referer", "agent", "null2")) %>%
  7. mutate_all(na_if, "-") %>%
  8. filter(user %>% is.na) %>%
  9. filter(!ip %in% c("192.168.0.254", "164.2.255.244")) %>%
  10. mutate(timestamp = timestamp %>% as.POSIXct(format = "[%d/%b/%Y:%H:%M:%S")) %>%
  11. separate(req, into = c("method", "url", "version"), sep = " ") %>%
  12. select(ip, timestamp, url, status, referer, agent) %>%
  13. dbWriteTable(conn = db, name = "access", value = ., append = T)
  14. known_ips <- character(0)
  15. db %>%
  16. tbl("geoip") %>%
  17. select(query) %>%
  18. collect %>%
  19. pull(query) -> known_ips
  20. db %>%
  21. tbl("access") %>%
  22. select(ip) %>%
  23. collect %>%
  24. pull(ip) %>%
  25. unique %>%
  26. setdiff(known_ips) -> ips
  27. if (length(ips) > 0)
  28. {
  29. ips %>%
  30. geolocate %>%
  31. select(ip = query, city, country, lat, lon) %>%
  32. dbWriteTable(conn = db, name = "geoip", value = ., append = T)
  33. }
  34. db %>%
  35. tbl("access") %>%
  36. left_join(db %>% tbl("geoip")) %>%
  37. collect -> geoaccess
  38. geoaccess %>%
  39. filter(status != 404,
  40. !agent %>% str_detect("bot")) %>%
  41. distinct(ip, lon, lat) %>%
  42. leaflet %>%
  43. addProviderTiles(providers$CartoDB.Positron) %>%
  44. addMarkers(~lon, ~lat, clusterOptions = markerClusterOptions())