日志數據分析之主帳號登錄、登出時間過於集中
1、一個分析場景,分析某公司主賬號登錄的集中情況,數據源為一個月登錄原始日志:
- ID MASTERLOGINID USERNAME PACKAGETIME CLIENTIP SERVERIP APPLICATIONID OPERATENAME OPERATETYPE RETURNCODE LOG_TYPE ORGNAME CONTENT
-
2、各個字段的意思:
日志id,主賬號,用戶姓名,操作時間,客戶端ip,服務器ip,應用系統id,操作名稱,操作類型,返回碼,日志類型,組織結構,操作內容
表結構:
- SQL> desc int_main_acct_login_100;
- Name Type Nullable Default Comments
- ------------- -------------- -------- ------- --------
- ID VARCHAR2(64)
- MASTERLOGINID VARCHAR2(50) Y
- USERNAME VARCHAR2(64) Y
- PACKAGETIME VARCHAR2(64) Y
- CLIENTIP VARCHAR2(32) Y
- SERVERIP VARCHAR2(256) Y
- APPLICATIONID NUMBER Y
- OPERATENAME VARCHAR2(1024) Y
- OPERATETYPE VARCHAR2(1024) Y
- RETURNCODE VARCHAR2(1024) Y
- LOG_TYPE VARCHAR2(32) Y
- ORGNAME VARCHAR2(1024) Y
- CONTENT VARCHAR2(4000) Y
- SQL>
3、執行分析,查看每分鐘、每天的登錄數量:
- select to_char(to_date(t.packagetime,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24'),count(t.operatetype) from int_main_acct_login_100 t group by to_char(to_date(t.packagetime,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24')
- order by to_char(to_date(t.packagetime,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24');
- TO_CHAR(TO_DATE(T.PACKAGETIME,COUNT(T.OPERATETYPE)
- 12016-05-01 0062
- 22016-05-01 0141
- 32016-05-01 0234
- 42016-05-01 0336
- 52016-05-01 0440
- 62016-05-01 0537
- 72016-05-01 0670
- 82016-05-01 07469
- 92016-05-01 081001
4、存在的問題和解決方案:
由於部分時間(某些小時、某些分鐘、某些天)沒人登錄,最終產生的數據的時間不連續,圖表的效果不好,根據和廠商一個開發人員溝通,創建一個常量的表,通過這個表進行兩個表關聯左連接查詢就可以了:
創建該表的話,通過存儲過程來處理:
首先創建表結構:
- create table yk_tb_time(mtime timestamp,pid number);
#oracle時間運算:
當前系統日期加1天:
select to_date(sysdate,'YYYY-MM-DD') +1 from dual;
當前系統日期加1分鐘:
select sysdate + 1/1440 from dual;
其中1440=1/(24*60)是一天之一分鐘
對varchar類型的“時間”轉成時間時(oracle中varchar類型的日期格式轉換date類型 )必須寫全:to_date(t.packagetime,'yyyy-mm-dd hh24:mi:ss'),要添加時分秒,不能寫成to_date(t.packagetime,'yyyy-mm-dd hh24'),然後再進行to_char處理:to_char(to_date(t.packagetime,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24')
創建存儲過程:
- create or replace procedure pro_yk_tb_time is
- i number :=0;
- begin
- while i <744 loop
- --select to_date('2016-5-1 0:0:1','yyyy-mm-dd hh24:mi:ss')+i/24 into ttime from dual;
- insert into yk_tb_time values(to_date('2016-5-1 0:0:1','yyyy-mm-dd hh24:mi:ss')+i/24,yk_seq.nextval);
- i:=i+1;
- end loop;
- --24 * 30 = 720,31day;
- --dbms_output.put_line(to_char(sysdate,'yyyy-mm-dd HH24:mi:ss'));
- commit;
- end pro_yk_tb_time
檢查:
select to_char(s.mtime,'yyyy-mm-dd hh24') from yk_tb_time s;
TO_CHAR(S.MTIME,'YYYY-MM-DDHH2
1 2016-05-01 00
2 2016-05-01 01
3 2016-05-01 02
4 2016-05-01 03
5 2016-05-01 04
6 2016-05-01 05
7 2016-05-01 06
8 2016-05-01 07
9 2016-05-01 08
最終版的sql腳本:
我的全量、常量信息表yk_tb_time要放到前面,因為我用的是左連接,如果放後面的話,下面提到的13號那行就出不來了:
- select to_char(s.mtime,'yyyy-mm-dd'),count(t.packagetime) from yk_tb_time s left join int_main_acct_login_100 t
- on to_char(to_date(t.packagetime,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd')=to_char(s.mtime,'yyyy-mm-dd') group by
- to_char(s.mtime,'yyyy-mm-dd') order by to_char(s.mtime,'yyyy-mm-dd');
- TO_CHAR(S.MTIME,'YYYY-MM-DD')COUNT(T.PACKAGETIME)
- 12016-05-01197640
- 22016-05-02166488
- 32016-05-03428592
- 42016-05-04306288
- 52016-05-05494160
- 62016-05-06481416
- 72016-05-07216816
生成圖表來看5月份登錄數量(13號那天沒人登錄數據,可能其他天某些分鐘也沒有;如果不這麼弄,那麼可以12、14號就是連續的,很難看出來中間有一天沒人登錄,這可能是有問題的):
之前寫的以分鐘為單位的圖表:
根據圖表,就可以看出登錄頻次多的時間了,設置一個阈值,就可以進一步生成分析結構了。