0

i must create some statistics out of a WWW access log database, but i found out that there are some redirect loops after a login if the user has disabled cookies. So there are 10-1000 mostly identical rows like the following:

...
/login?redirect=/app - 200 - 123.123.123.123 - 2014-01-01 10:00:00
/app                 - 403 - 123.123.123.123 - 2014-01-01 10:00:00
/login?redirect=/app - 200 - 123.123.123.123 - 2014-01-01 10:00:00
/app                 - 403 - 123.123.123.123 - 2014-01-01 10:00:01
...

Is there a way to detect unusal count grouped by the ip/url in an interval? I think i need to select all counts for each minute an detect a spike and ignore that... Does anyone had the same difficulties?

7
  • Do you have the different fields of the access log available as different columns? Commented Aug 4, 2014 at 11:42
  • This kind of query is very easy with window functions -- specifically lag and lead, but I don't think MySQL has these. Commented Aug 4, 2014 at 11:43
  • @Colin'tHart Yes of course, everything is in it's own column, hence the "-". The tables contains way more columns but these are not relevant for my problem...
    – Constantin
    Commented Aug 4, 2014 at 11:58
  • @Constantin So how would you define a "spike", more than N hits in the same minute by the same user, on the same URL, with a particular code, all of them?
    – jynus
    Commented Aug 4, 2014 at 17:04
  • @jynus Basically there are some redirect loops due to the fact that some users block cookies... so a typical request i have is something like: normal html site with a link to a dynamic application which required a login (the login may be a default user auto login), so a click on the application link redirects to the login, because the user isn't logged in yet, the login detects if the user is a default user and may login the user as a default user and redirect back to the dynamic application, but if cookies are blocked. this redirect loops forever if the user does not know whats going on
    – Constantin
    Commented Aug 5, 2014 at 7:34

1 Answer 1

0

Acoording to your pattern, you could do something like this (change your column names and url pattern accordingly):

mysql> SET @max_redirects := 10;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT count(*) as `# redirects`, ip, min(url) as url, 
              time_event - INTERVAL SECOND(time_event) SECOND AS minute 
       FROM log WHERE url like '/login?redirect=%' 
       GROUP BY ip, minute 
       HAVING `# redirects` > @max_redirects;
+-------------+-----------------+----------------------+---------------------+
| # redirects | ip              | url                  | minute              |
+-------------+-----------------+----------------------+---------------------+
|          53 | 1.1.1.1         | /login?redirect=/    | 2014-08-05 08:03:00 |
|          21 | 1.1.1.1         | /login?redirect=/    | 2014-08-05 08:05:00 |
|         128 | 123.123.123.123 | /login?redirect=/app | 2014-01-01 10:00:00 |
+-------------+-----------------+----------------------+---------------------+
3 rows in set (0.01 sec)

Expect this to be slow on a tall table, so add an index on your timestamp column and filter by date to avoid huge sorts.

4
  • Thanks, i think that gets me working... but it is, as you said, pretty slow, even with all nesessary indexes
    – Constantin
    Commented Aug 6, 2014 at 9:37
  • @Constantin It can be easily improved, but you would need a couple of changes in structure, that I do not know if you can do or if the original table supports it.
    – jynus
    Commented Aug 6, 2014 at 9:56
  • The table only has the following columns: id,e_url,e_full_url,e_time,e_method,e_status,e_length,e_referer,e_ip,e_country,e_city,ua_name,ua_version,ua_full,os_name,os_version,os_family,e_ignore,e_internal. The database is kind of old but could or should be replaced if necessary. Old data could be imported. (e_url is varchar(254) to be indexed, e_full_url contains the full url with query string)
    – Constantin
    Commented Aug 6, 2014 at 13:04
  • Maybe another info: each month is stored in an own table. each tables has 5-6m rows, trending up. bots and some files(js,css,jpg,png,ico) already filtered out, because we do not need these information in the database.
    – Constantin
    Commented Aug 6, 2014 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.