FormatImporter
1. FormatImporter 概述
FormatImporter 用於將一些常見格式的外部數據匯入到神策分析,目前支援讀取 csv 表格、Nginx Log、mysql 資料庫、oracle 資料庫,以及符合 數據格式 的 json 數據。
下載請點擊此連結,腳本下載後是一個壓縮包,注意執行此腳本需要 python3.4。另外如果需要匯入 mysql、oracle 數據庫中的數據的話需要確保電腦上包含相關用戶端的程式包。
注意:當匯入數據到神策之前,請確認數據中 distinct_id 是登入 id 還是匿名 id。若是登入 id,則需在匯入命令中增加參數 --is_login,詳情請見下面範例場景。
2. 經典使用方法
2.1. 取得數據接收網址
首先從神策分析的主頁中,取得數據接收的 URL 和 Token(Cloud 版)。
如果使用神策分析 Cloud 服务,需取得的設定資訊為:
- 數據接收網址,建議使用不帶埠號的: http://{$service_name}.datasink.sensorsdata.cn/sa?project={$project_name}&token={$project_token}
- 數據接收網址,帶埠號的: http://{$service_name}.cloud.sensorsdata.cn:8106/sa?project={$project_name}&token={$project_token}
如果用戶使用單機版私有部署的神策分析,預設的設定資訊為:
數據接收網址: http://{$host_name}:8106/sa?project={$project_name}
(注:神策分析 1.7 及之前的版本,單機版私有部署預設埠號為 8006)
如果用戶使用叢集版私有部署的神策分析,預設的設定資訊为:
數據接收網址: http://{$host_name}:8106/sa?project={$project_name}
其中 {$host_name} 可以是叢集中任意一台電腦。
如果私有部署的過程中修改了 Nginx 的預設設定,或透過 CDN 等連接神策分析,則請諮詢相關人員取得設定資訊。
2.2. 範例場景
假設有一個電商網站,需要採集以下用戶事件:
- 瀏覽事件,包括瀏覽的商品名稱 ( item_name ) 和商品 id ( item_id)
- 購買事件,包括購買的商品名稱 ( item_name ) 和商品 id ( item_id)
範例事件如下
用戶 | 事件 | 時間 | 商品id | 商品名稱 |
---|---|---|---|---|
bug29 | 瀏覽 | 2018-05-12 13:01:11 | 13245 | 男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒 |
bug29 | 購買 | 2018-05-12 13:05:03 | 13245 | 男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒 |
小武 | 瀏覽 | 2018-05-13 10:20:32 | 23421 | New Order Technique 2CD豪華版 歐版行貨 全新未拆 |
菠菜 | 瀏覽 | 2018-05-13 20:42:53 | 3442 | NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型 |
並採集以下用戶屬性:
* 用戶的性別 ( gender ),男或女
* 用戶是否是會員 ( is_member )
* 用戶的會員積分 ( score )
範例用戶屬性如下
用戶名 | 性别 | 是否為會員 | 會員積分 |
---|---|---|---|
bug29 | 男 | 是 | 131 |
小武 | 女 | 否 | <沒有積分> |
2.3. 匯入 csv 格式的數據
2.3.1. 匯入事件
假設有以下 csv 檔案描述了上面的範例用戶事件 ( 參考程式碼包 examples/events.csv )。
user_id,action,time,item_id,item_name,item_cate
bug29,view,2018-05-12 13:01:11,13245,男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒,男裝
bug29,buy,2018-05-12 13:05:03,13245,男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒,男裝
小武,view,2018-05-13 10:20:32,23421,New Order Technique 2CD豪華版 歐版行貨 全新未拆,音像
菠菜,view,2018-05-13 20:42:53,3442,NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型,母嬰
將這些數據匯入到本地私有部署的環境,以 user_id 作為用戶的 id,以 time 作為事件發生的時間,以 action 作為事件名稱,只匯入 item_id 和 item_name 作為事件屬性。
注意:若匯入事件名為 $SignUp 事件的 csv 格式的數據,在神策裡不會寫用戶關聯關係,只會作為普通事件寫入事件表。
python3 format_importer.py csv_event \
--url 'http://localhost:8106/sa?project=xxx' \
--distinct_id_from 'user_id' \
--is_login \ # 標識 distinct_id 為登入 id,若 distinct_id 為匿名 id,則去掉--is_login
--timestamp_from 'time' \
--event_from 'action' \
--filename './examples/events.csv' \
--property_list 'item_id,item_name' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/csv_event.conf )。
url: http://localhost:8106/sa
distinct_id_from: user_id
is_login
event_from: action
timestamp_from: time
filename: ./examples/events.csv
property_list: item_id,item_name
debug
然後執行
python3 format_importer.py csv_event @./conf/csv_event.conf
2.3.2. 匯入用戶屬性
假設有以下 csv 檔案描述了上面的範例用戶屬性 ( 參考程式碼包 examples/profiles.csv )。
user_id,gender,is_member,score
bug29,男,true,131
小武,女,false,
將這些數據匯入到本地私有部署的環境,以 user_id 作為用戶的 id。
python3 format_importer.py csv_profile \
--url 'http://localhost:8106/sa?project=xxx' \
--distinct_id_from 'user_id' \
--is_login \ # 標識 distinct_id 為登入 id,若 distinct_id 為匿名 id,則去掉--is_login
--filename './examples/profiles.csv' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/csv_profile.conf )。
url: http://localhost:8106/sa?project=xxx
distinct_id_from: user_id
is_login
filename: ./examples/profiles.csv
debug
然後執行
python3 format_importer.py csv_profile @./conf/csv_profile.conf
2.3.3. 匯入 item 數據
假設有以下 csv 檔案描述了上面的範例用戶事件 ( 參考程式碼包 examples/item.csv )。
item_type,item_id,item_name,item_cate,action
view,13245,男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒,男裝,買買買
buy,13245,男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒,男裝,缺貨
view,23421,New Order Technique 2CD豪華版 歐版行貨 全新未拆,音像,缺貨
view,3442,NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型,母嬰,買買
將數據匯入 item 表中,--item_type 和 --item_id 指令分別指定 item 數據的 item_type 和 item_id 欄位值
python3 format_importer.py csv_item \
--url 'http://localhost:8106/sa?project=xxx' \
--item_type 'item_type' \
--item_id 'item_id' \
--property_list 'item_name,item_cate,action' \
--filename './examples/item.csv' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/csv_item.conf )。
url: http://localhost:8106/sa?project=xxx
item_type: item_type
item_id: item_id
filename: ./examples/events.csv
debug
然後執行
python3 format_importer.py csv_item @./conf/csv_item.conf
2.4. 匯入 nginx log
2.4.1. 匯入事件
假設有以下 nginx log 描述了上面的範例用戶事件 ( 參考程式碼包 examples/events.log )。
123.4.5.6 - [12/May/2018:13:01:11 +0800] "GET /item?id=13245&action=view&cate=%e7%94%b7%e8%a3%85" 200 1127 "Mozilla/5.0 ( Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36" "http://fake_web.com/login.html" "男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒" "bug29"
123.4.5.6 - [12/May/2018:13:05:03 +0800] "GET /item?id=13245&action=buy&cate=%e7%94%b7%e8%a3%85" 200 1127 "Mozilla/5.0 ( Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36" "http://fake_web.com/login.html" "男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒" "bug29"
123.4.5.7 - [13/May/2018:10:20:32 +0800] "GET /item?id=23421&action=view&cate=%e9%9f%b3%e5%83%8f" 200 1127 "Mozilla/5.0 ( Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "http://www.baidu.com?q=abc" "New Order Technique 2CD豪華版歐版行貨全新未拆" "小武"
123.8.5.7 - [13/May/2018:20:42:53 +0800] "GET /item?id=&action=view&cate=%e6%af%8d%e5%a9%b4" 200 1127 "Mozilla/5.0 ( Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "http://www.baidu.com?q=abc" "NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型" "菠菜"
對應 nginx 設定的格式如下:
log_format compression '$remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$title" "$user_id"';
access_log /data/nginx_log/access.log compression;
將這些數據匯入到本地私有部署的環境,以$user_id 作為用戶的id,以$time_local 作為事件發生的時間,$reqeust 解析後的參數action 對應的值是事件名,只匯入兩個事件屬性: $request 解析後的id 作為item_id,自定義的變量$title 作為item_name。
python3 format_importer.py nginx_event \
--url 'http://localhost:8106/sa?project=xxx' \
--distinct_id_from 'user_id' \
--is_login \ # 標識 distinct_id 為登入 id,若 distinct_id 為匿名 id,則去掉--is_login
--timestamp_from 'time_local' \
--timestamp_format '%d/%b/%Y:%H:%M:%S %z' \
--event_from '__request_param_action' \
--filename './examples/events.log' \
--log_format '$remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$title" "$user_id"' \
--property_list '__request_param_id,title' \
--property_list_cnames 'item_id,item_name' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/nginx_event.conf )。
url: http://localhost:8106/sa?project=xxx
distinct_id_from: user_id
is_login
event_from: __request_param_action
timestamp_from: time_local
timestamp_format: %d/%b/%Y:%H:%M:%S %z
filename: ./examples/events.log
log_format: $remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$title" "$user_id"
property_list: __request_param_id,title
property_list_cnames: item_id,item_name
debug
然後執行
python3 format_importer.py nginx_event @./conf/nginx_event.conf
2.4.2. 匯入用戶屬性
假設有以下 nginx log 描述了上面的範例用戶屬性 ( 參考程式碼包 examples/profiles.log )。
123.4.5.6 - [12/May/2018:13:01:11 +0800] "POST /profile?user=bug29&is_member=true" 200 1127 "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36" "http://fake_web.com/login.html" "男" "131"
123.4.5.7 - [13/May/2018:10:20:32 +0800] "POST /profile?user=%e5%b0%8f%e6%ad%a6&is_member=false" 200 1127 "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "http://www.baidu.com?q=abc" "女" ""
對應 nginx 設定的格式如下:
log_format compression '$remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$gender" "$score"';
access_log /data/nginx_log/access.log compression;
將這些數據匯入到本地私有部署的環境,以 $reqeust 解析後的參數 user 作為用戶的 id,匯入三個用戶屬性: 自定義變量 $gender 和 $score ,以及 $reqeust 解析後的參數 is_member。
python3 format_importer.py nginx_profile \
--url 'http://localhost:8106/sa?project=xxx' \
--distinct_id_from '__request_param_user' \
--is_login \ # 標識 distinct_id 為登入 id,若 distinct_id 為匿名 id,則去掉--is_login
--filename './examples/profiles.log' \
--log_format '$remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$gender" "$score"' \
--property_list 'gender,score,__request_param_is_member' \
--property_list_cnames 'gender,score,is_member' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/nginx_profile.conf )。
url: http://localhost:8106/sa?project=xxx
distinct_id_from: __request_param_user
is_login
filename: ./examples/profiles.log
log_format: $remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$gender" "$score"
property_list: gender,score,__request_param_is_member
property_list_cnames: gender,score,is_member
debug
然後執行
python3 format_importer.py nginx_profile @./conf/nginx_profile.conf
2.4.3. 匯入 item 數據
假設有以下 nginx log 描述了上面的範例用戶屬性 ( 參考程式碼包 examples/item.log )。
123.4.5.6 - [12/May/2018:13:01:11 +0800] "GET /item?id=13245&action=view&cate=%e7%94%b7%e8%a3%85" 200 1127 "Mozilla/5.0 ( Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36" "http://fake_web.com/login.html" "男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒" "bug29"
123.4.5.6 - [12/May/2018:13:05:03 +0800] "GET /item?id=13245&action=buy&cate=%e7%94%b7%e8%a3%85" 200 1127 "Mozilla/5.0 ( Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36" "http://fake_web.com/login.html" "男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒" "bug29"
123.4.5.7 - [13/May/2018:10:20:32 +0800] "GET /item?id=23421&action=view&cate=%e9%9f%b3%e5%83%8f" 200 1127 "Mozilla/5.0 ( Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "http://www.baidu.com?q=abc" "New Order Technique 2CD豪華版歐版行貨全新未拆" "小武"
123.8.5.7 - [13/May/2018:20:42:53 +0800] "GET /item?id=&action=view&cate=%e6%af%8d%e5%a9%b4" 200 1127 "Mozilla/5.0 ( Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "http://www.baidu.com?q=abc" "NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型" "菠菜"
對應 nginx 設定的格式如下:
log_format compression '$remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$title" "$user_id"';
access_log /data/nginx_log/access.log compression;
將這些數據匯入到本地私有部署的環境,以 $reqeust 解析後的參數 user 作為用戶的 id,匯入三個用戶屬性: 自定義變量 $gender 和 $score ,以及 $reqeust 解析後的參數 is_member。
python3 format_importer.py nginx_item \
--url 'http://localhost:8106/sa?project=xxx' \
--item_id 'user_id' \
--item_type '__request_param_action' \
--filename './examples/item.log' \
--log_format '$remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$title" "$user_id"' \
--property_list '__request_param_id,title' \
--property_list_cnames '$gender,$score' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/nginx_item.conf )。
url: http://localhost:8106/sa?project=xxx
item_id: user_id
filename: ./examples/profiles.log
log_format: $remote_addr [$time_local] "$request" $status $bytes_sent "$http_user_agent" "$http_referer" "$gender" "$score"
property_list: gender,score,__request_param_is_member
property_list_cnames: gender,score,is_member
debug
然後執行
python3 format_importer.py nginx_item @./conf/nginx_item.conf
2.5. 匯入 mysql 的數據
注意使用 mysql 匯入需要先安裝函式庫,請執行下面命令來安裝 PyMySQL。
python3 -m pip install PyMySQL --upgrade
2.5.1. 匯入事件
假設有以下 mysql 表描述了上面的範例用戶事件 ( 參考程式碼包 examples/events.sql )。
drop table if exists events;
create table events (
user_id varchar(100),
action varchar(100),
time timestamp,
item_id int,
item_name text,
item_cate varchar(100));
insert into events values('bug29', 'view', '2018-05-12 13:01:11', 13245, '男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒', '男裝');
insert into events values('bug29', 'buy', '2018-05-12 13:05:03', 13245, '男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒', '男裝');
insert into events values('小武', 'view', '2018-05-13 10:20:32', 23421, 'New Order Technique 2CD豪華版 歐版行貨 全新未拆', '音像');
insert into events values('菠菜', 'view', '2018-05-13 20:42:53', 3442, 'NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型', '母嬰');
將這些數據匯入到本地私有部署的環境,以 user_id 作為用戶的 id,以 time 作為事件發生的時間,以 action 作為事件名稱,只匯入 item_id 和 item_name 作為事件屬性。最後的 ORDER BY 主要是確保多次查詢數據順序一致,這樣假如匯入一半失敗了,可以使用我們的參數跳過匯入成功的行數。
注意:若匯入事件名為 $SignUp 事件的 mysql 的數據,在神策裡不會寫用戶關聯關係,只會作為普通事件寫入事件表。
python3 format_importer.py mysql_event \
--url 'http://localhost:8106/sa?project=xxx' \
--distinct_id_from 'user_id' \
--is_login \ # 標識 distinct_id 為登入 id,若 distinct_id 為匿名 id,則去掉--is_login
--timestamp_from 'time' \
--event_from 'action' \
--user 'root' \
--password 'pass' \
--host 'localhost' \
--port 3307 \
--db 'test_db' \
--sql 'select user_id, action, time, item_id, item_name from events order by time;' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/mysql_event.conf )。
url: http://localhost:8106/sa?project=xxx
distinct_id_from: user_id
is_login
event_from: action
timestamp_from: time
user: root
password: pass
host: localhost
port: 3307
db: test_db
sql: select user_id, action, time, item_id, item_name from events order by time;
debug
然後執行
python3 format_importer.py mysql_event @./conf/mysql_event.conf
2.5.2. 匯入用戶屬性
假設有以下 mysql 表描述了上面的範例用戶屬性 ( 參考程式碼包 examples/profiles.sql )。
drop table if exists profiles;
create table profiles (
user_id varchar(100),
gender varchar(20),
is_member bool,
score int);
insert into profiles values('bug29', '男', true, 131);
insert into profiles values('小武', '女', false, null);
將這些數據匯入到本地私有部署的環境,以 user_id 作為用戶的 id,匯入全部用戶屬性。最後的 ORDER BY 主要是確保多次查詢數據順序一致,這樣假如匯入一半失敗了,可以使用我們的參數跳過匯入成功的行數。
python3 format_importer.py mysql_profile \
--url 'http://localhost:8106/sa?project=xxx' \
--distinct_id_from 'user_id' \
--is_login \ # 標識 distinct_id 為登入 id,若 distinct_id 為匿名 id,則去掉--is_login
--user 'root' \
--password 'pass' \
--host 'localhost' \
--port 3307 \
--db 'test_db' \
--sql 'select user_id, gender, is_member, score from profiles order by user_id;' \
--bool_property_list 'is_member' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包下 conf/mysql_profile.conf )。
url: http://localhost:8106/sa?project=xxx
distinct_id_from: user_id
is_login
user: root
password: pass
host: localhost
port: 3307
db: test_db
sql: select user_id, gender, is_member, score from profiles order by user_id;
bool_property_list: is_member
debug
然後執行
python3 format_importer.py mysql_profile @./conf/mysql_profile.conf
2.5.3. 匯入 item 數據
假設有以下 mysql 表描述了上面的範例用戶事件 ( 參考程式碼包 examples/events.sql )。
drop table if exists events;
create table events (
user_id varchar(100),
action varchar(100),
time timestamp,
item_id int,
item_name text,
item_cate varchar(100));
insert into events values('bug29', 'view', '2018-05-12 13:01:11', 13245, '男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒', '男裝');
insert into events values('bug29', 'buy', '2018-05-12 13:05:03', 13245, '男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒', '男裝');
insert into events values('小武', 'view', '2018-05-13 10:20:32', 23421, 'New Order Technique 2CD豪華版 歐版行貨 全新未拆', '音像');
insert into events values('菠菜', 'view', '2018-05-13 20:42:53', 3442, 'NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型', '母嬰');
將這些數據匯入到本地私有部署的環境,以數據庫中的 item_id 作為 item 數據的 item_id,以數據庫的 action 作為 item_type 。最後的 ORDER BY 主要是確保多次查詢數據順序一致,這樣假如匯入一半失敗了,可以使用我們的參數跳過匯入成功的行數。
format_importer.py mysql_item \
--url 'http://localhost:8106/sa?project=xxx' \
--item_type 'action' \
--item_id 'item_id' \
--user 'root' \
--password 'root1234' \
--host 'localhost' \
--port 3306 \
--db 'sa_item' \
--sql 'select user_id, gender, is_member, score from profiles order by user_id' \
--debug \ # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/mysql_event.conf )。
url: http://localhost:8106/sa?project=xxx
item_id: user_id
item_type: action
user: root
password: pass
host: localhost
port: 3307
db: test_db
sql: select user_id, gender, is_member, score from profiles order by user_id;
debug
然後執行
python3 format_importer.py mysql_event @./conf/mysql_item.conf
2.6. 匯入 json 格式的 log
用戶也可以將 log 寫入檔案中,每行是一個 數據格式 表示事件或屬性或者 item 數據。假設有以下 log 描述了上面的範例的事件、用戶屬性、item 數據 ( 參考程式碼包 examples/json_data.json )。
{"type":"track","time":1526101271000,"distinct_id":"bug29","properties":{"item_id":13245.0,"item_name":"\u7537\u58eb\u62a4\u8033\u4fdd\u6696\u9e2d\u820c\u76ae\u5e3d\u5e73\u9876\u516b\u89d2\u5e3d\u5934\u5c42\u725b\u76ae\u5e3d\u5b50\u65f6\u5c1a\u4f11\u95f2"},"event":"view","time_free":true}
{"type":"track","time":1526101503000,"distinct_id":"bug29","properties":{"item_id":13245.0,"item_name":"\u7537\u58eb\u62a4\u8033\u4fdd\u6696\u9e2d\u820c\u76ae\u5e3d\u5e73\u9876\u516b\u89d2\u5e3d\u5934\u5c42\u725b\u76ae\u5e3d\u5b50\u65f6\u5c1a\u4f11\u95f2"},"event":"buy","time_free":true}
{"type":"track","time":1526178032000,"distinct_id":"\u5c0f\u6b66","properties":{"item_id":23421.0,"item_name":"New Order Technique 2CD\u8c6a\u534e\u7248 \u6b27\u7248\u884c\u8d27 \u5168\u65b0\u672a\u62c6"}, "event":"view","time_free":true}
{"type":"track","time":1526215373000,"distinct_id":"\u83e0\u83dc","properties":{"item_id":3442.0,"item_name":"NUK\u5b89\u629a\u5976\u5634\u5b9d\u5b9d\u9632\u80c0\u6c14\u5b89\u6170\u5976\u5634\u4e73\u80f6\u8fea\u58eb\u5c3c\u5b89\u7761\u578b"},"event":"view","time_free":true}
{"type":"profile_set","time":1526263297951,"distinct_id":"bug29","properties":{"gender":"\u7537","is_member":true,"score":131.0},"time_free":true}
{"type":"profile_set","time":1526263297951,"distinct_id":"\u5c0f\u6b66","properties":{"gender":"\u5973","is_member":false},"time_free":true}
{"type":"item_set","properties":{"name":"yuejz","OrderPaid":12.1},"item_id":"item_id","time":1566022866941,"item_type":"item_type"}
{"type":"item_set","properties":{"name":"yuejz"},"item_id":"item_id","time":1566022866941,"item_type":"item_type"}
{"type":"item_set","time":1566023226152,"properties":{"OrderTime":"2019-07-01 12:02:36","OrderPaid":12.1},"item_id":"item_id","item_type":"item_type"}
{"type":"itpe":"profile_set","time":1526263297951,"distinct_id":"\u5c0f\u6b66","properties":{"gender":"\u5973","is_member":false},"time_free":true}
將這些數據匯入到本地私有部署的環境,
注意:若事件或屬性數據中 distinct_id 為登入 id,需在 properties 裡增加 "$is_login_id":true 屬性來標識。
python3 format_importer.py json \
--url 'http://localhost:8106/sa?project=xxx' \
--path './examples/json_data.json' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入 json.conf
url: http://localhost:8106/sa?project=xxx
path: ./examples/events_and_profiles.json
debug
然後執行
python3 format_importer.py json @./conf/json.conf
2.7. 匯入 oracle 的數據
注意使用 oracle 匯入需要先安裝函式庫,請執行下面命令來安裝 cx_Oracle 並需要確保電腦上包含了相關 oracle 用戶端程式包。
python3 -m pip install cx_Oracle --upgrade
2.7.1. 匯入事件
假設有以下 oracle 表描述了上面的範例用戶事件 ( 參考程式碼包 examples/events.plsql )。
drop table if exists events;
create table events (
user_id varchar(100),
action varchar(100),
time timestamp,
item_id int,
item_name text,
item_cate varchar(100));
insert into events values('bug29', 'view', '2018-05-12 13:01:11', 13245, '男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒', '男裝');
insert into events values('bug29', 'buy', '2018-05-12 13:05:03', 13245, '男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒', '男裝');
insert into events values('小武', 'view', '2018-05-13 10:20:32', 23421, 'New Order Technique 2CD豪華版 歐版行貨 全新未拆', '音像');
insert into events values('菠菜', 'view', '2018-05-13 20:42:53', 3442, 'NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型', '母嬰');
將這些數據匯入到本地私有部署的環境,以 user_id 作為用戶的 id,以 time 作為事件發生的時間,以 action 作為事件名稱,只匯入 item_id 和 item_name 作為事件屬性。最後的 ORDER BY 主要是確保多次查詢數據順序一致,這樣假如匯入一半失敗了,可以使用我們的參數跳過匯入成功的行數。
注意:若匯入事件名為 $SignUp 事件的 oracle 的數據,在神策裡不會寫用戶關聯關係,只會作為普通事件寫入事件表。
python3 format_importer.py oracle_event \
--url 'http://localhost:8106/sa?project=xxx' \
--distinct_id_from 'user_id' \
--is_login \ # 標識 distinct_id 為登入 id,若 distinct_id 為匿名 id,則去掉--is_login
--timestamp_from 'time' \
--event_from 'action' \
--user 'root' \
--password 'pass' \
--dsn '127.0.0.1/orcl' \
--sql 'select user_id, action, time, item_id, item_name from events order by time' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/oracle_event.conf )。
url: http://localhost:8106/sa?project=xxx
distinct_id_from: user_id
is_login
event_from: action
timestamp_from: time
user: root
password: pass
dsn: 127.0.0.1/orcl
sql: select user_id, action, time, item_id, item_name from events order by time;
debug
然後執行
python3 format_importer.py oracle_event @./conf/oracle_event.conf
2.7.2. 匯入用戶屬性
假設有以下 oracle 表描述了上面的範例用戶屬性 ( 參考程式碼包 examples/profiles.plsql )。
drop table if exists profiles;
create table profiles (
user_id varchar(100),
gender varchar(20),
is_member bool,
score int);
insert into profiles values('bug29', '男', true, 131);
insert into profiles values('小武', '女', false, null);
將這些數據匯入到本地私有部署的環境,以 user_id 作為用戶的 id,匯入全部用戶屬性。最後的 ORDER BY 主要是確保多次查詢數據順序一致,這樣假如匯入一半失敗了,可以使用我們的參數跳過匯入成功的行數。
python3 format_importer.py oracle_profile \
--url 'http://localhost:8106/sa?project=xxx' \
--distinct_id_from 'user_id' \
--is_login \ # 標識 distinct_id 為登入 id,若 distinct_id 為匿名 id,則去掉--is_login
--user 'root' \
--password 'pass' \
--dsn '127.0.0.1/orcl \
--sql 'select user_id, gender, is_member, score from profiles order by user_id' \
--bool_property_list 'is_member' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/oracle_profile.conf )。
url: http://localhost:8106/sa?project=xxx
distinct_id_from: user_id
is_login
user: root
password: pass
dsn: 127.0.0.1/orcl
sql: select user_id, gender, is_member, score from profiles order by user_id
bool_property_list: is_member
debug
然後執行
python3 format_importer.py oracle_profile @./conf/oracle_profile.conf
2.7.3. 匯入 item 數據
假設有以下 oracle 表描述了上面的範例用戶事件 ( 參考程式碼包 examples/events.plsql )。
drop table if exists events;
create table events (
user_id varchar(100),
action varchar(100),
time timestamp,
item_id int,
item_name text,
item_cate varchar(100));
insert into events values('bug29', 'view', '2018-05-12 13:01:11', 13245, '男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒', '男裝');
insert into events values('bug29', 'buy', '2018-05-12 13:05:03', 13245, '男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒', '男裝');
insert into events values('小武', 'view', '2018-05-13 10:20:32', 23421, 'New Order Technique 2CD豪華版 歐版行貨 全新未拆', '音像');
insert into events values('菠菜', 'view', '2018-05-13 20:42:53', 3442, 'NUK安撫奶嘴寶寶防脹氣安慰奶嘴乳膠迪士尼安睡型', '母嬰');
將這些數據匯入到本地私有部署的環境,以數據庫中的 item_id 作為item 數據的 item_id,以數據庫的 action 作為 item 數據的 item_type,只匯入 item_cate 和 item_name 作為事件屬性。最後的 ORDER BY 主要是確保多次查詢數據順序一致,這樣假如匯入一半失敗了,可以使用我們的參數跳過匯入成功的行數。
python3 format_importer.py oracle_item \
--url 'http://localhost:8106/sa?project=xxx' \
--item_id 'item_id' \
--item_type 'action' \
--user 'root' \
--password 'pass' \
--dsn '127.0.0.1/orcl' \
--sql 'select item_id, action, item_cate, item_name from events order by time' \
--debug # 校驗數據格式,不會匯入數據,正式使用的時候去掉--debug
也可以將上述參數寫入設定檔案中 ( 參考程式碼包 conf/oracle_item.conf )。
url: http://localhost:8106/sa?project=xxx
item_id: user_id
item_type: action
user: root
password: pass
dsn: 127.0.0.1/orcl
sql: select item_id, action, item_cate, item_name from events order by time;
debug
然後執行
python3 format_importer.py oracle_item @./conf/oracle_item.conf
3. 使用建議
1. 先選用部分數據,增加 --debug 選項測試通過後再正式匯入。增加 --debug 後進入除錯模式,不會匯入數據。對於每條數據,若成功則發送的數據列到標準輸出上,否則會列印出錯資訊。執行完畢之後列印讀取多少條,錯誤多少條。
匯入 csv / nginx log 的時候,可以先用 head -1000 file_name > test_file 的方式先匯入一部分數據到測試檔案,然後使用測試檔案匯入
匯入 mysql 數據的時候,可以在查詢語句後面加上 LIMIT 1000 然後測試匯入
2. 執行時在 format_importer 目錄下會產生 log, log 名為 format_importer.log,包含比輸出更全的除錯資訊,如果增加 --debug 後螢幕上輸出比較多,可以查看 log 查找出錯資訊和除錯資訊。
3. 由於參數比較複雜,建議 使用設定檔案的方式傳遞參數,具體設定檔案範例可以解壓後查看 conf 目錄。
4. 對於 csv log 匯入,需要確保 log 檔是有效的 csv 格式,建議先閱讀 csv 轉義 相關的內容。
5. 由於 nginx 的 log 格式所限,匯入的 property 的名字可能看起來並不具有可讀性,比如 __request_param_action 這樣的,強烈建議使用 property_list_cnames 來轉化成可讀的屬性名。
6. 對於mysql 匯入,如果sql 語句寫的比較長的時候,容易出現sql 傳遞給程式後shell 轉義錯誤的問題,建議錯誤時查看在format_impoter 目錄下的 log,會在啟動後第一條 log 裡面寫上傳遞的參數,請仔細查看和傳遞的sql 是否一致。另外建議如果 sql 比較長,建議使用 --filename 的方式寫入檔案傳遞。
7. 對於 mysql 匯入,如果 sql 語句是兩個表的 join, 那麼指定列名的時候需要指定的是別名或者列名,而不是<表名>.<列名>。詳細解釋參見 用 mysql 將兩張表 join 起來匯入,明明有數據為什麼提示我 distinct_id / timestamp / event 為空。
8. 如果需要更高效率匯入,建議先使用 --output_file 來導出到 log 檔中去,然後使用 BatchImporter 或者 HDFSImporter匯入到叢集中去。
4. 使用方法詳解
4.1. 子命令說明
子命令就是跟在執行腳本後的第一個參數,比如 2.1 中執行
python3 format_importer.py csv_event \
--url 'http://localhost:8106/sa?project=xxx' \
--event_default 'UserBuy' \
--distinct_id_from 'user' \
--timestamp_from 'buy_time' \
--filename 'buy.csv'
使用的子命令是 csv_event,表示 csv 格式數據匯入為event。目前支援以下7種子命令。
自命令名稱 | 解釋 |
---|---|
csv_profile | 將 csv 格式檔案匯入, 匯入 profile |
csv_event | 將 csv 格式檔案匯入, 匯入event |
csv_item | 將 csv 格式檔案匯入, 匯入 item |
mysql_profile | 提供 sql,將 mysql 的數據匯入, 匯入 profile |
mysql_event | 提供 sql,將 mysql 的數據匯入, 匯入 event |
mysql_item | 提供 sql,將 mysql 的數據匯入, 匯入 item |
nginx_profile | 將 Nginx Log 匯入, 匯入 profile |
nginx_event | 將 Nginx Log 匯入, 匯入 event |
nginx_item | 將 Nginx Log 匯入, 匯入 item |
json | 將 Json Log匯入,注意 Log 不區分 event、profile、item |
oracle_profile | 提供 sql,將 oracle 的數據匯入, 匯入 profile |
oracle_event | 提供 sql,將 oracle 的數據匯入, 匯入 event |
oracle_item | 提供 sql,將 oracle 的數據匯入, 匯入 item |
如果想看單個子命令支援哪些參數,可以在子命令之後加 -h,將取得所有的參數和說明,如
python3 format_importer.py csv_event -h
python3 format_importer.py json -h
4.2. 從設定檔案中匯入
format_importer 支援從設定檔案中讀取參數,使用方法是在子命令之後增加 @<設定檔案路徑>。下載後的原始碼包裡面即包含了預設的幾個設定,在 conf 目錄下,可以修改後使用設定檔案匯入。
舉例想匯入 csv 的 event,可以修改 conf/csv_event.conf,然後執行
python3 format_importer.py csv_event @./conf/csv_event.conf
4.3. 公共參數
通用的公共參數包括:
參數名 | 別名 | 是否必填 | 解釋 |
---|---|---|---|
--url | -l | 和 output_file 選一個必填 | 發送數據的 url,取得方式在 2.1 節已經進行過描述。 |
--output_file | -O | 和 url 選一個必填 | 輸出的檔案名,輸出每行是一個符合格式的json。 |
--project | -j | 否 | 指定的project名,預設是default |
--skip_cnt | -c | 否 | 第一次執行請忽略,如果執行失敗,需要跳過成功的那幾行,這個就是指定跳過幾行的。 |
--debug | -D | 否 | 如果指定了就是使用debug模式,不會匯入數據,只在stdout顯示數據,參見除錯模式 |
--quit_on_error | -Q | 否 | 如果選中,則出現一條錯誤 log 就會退出 |
此外,匯入 csv log / nginx log / mysql 數據時需要區分是匯入 event 還是 profile,二者有不同的公共參數;匯入 json log 時,只支援設定如上的公共參數。
4.4. event/profile/item 公共參數
對於profile, 匯入需要指定哪一列作為 distinct_id.
對於 event,除了指定 distinct_id,還需要指定 event 和 timestamp。指定 event 目前支援兩種方法,一種將所有的數據都認為是同一個 event,另一種是指定哪一列作為 event。同樣指定 timestamp 目前支援兩種方法,一種將所有數據都認為是同一個 timestamp,另一種是指定哪一列作為 timestamp。
對應 item,必須指定 item_type 和 item_id。
參數名 | 别名 | 匯入 profile 是否需要 | 匯入 event 是否需要 | 匯入 item 是否需要 | 解釋 |
---|---|---|---|---|---|
--distinct_id_from | -df | 必填 | 必填 | 不可以填 | 從哪個欄位作為 distinct_id,如果指定,則每條數據算作對應欄位的用戶的行為。 |
--is_login | 選填 | 選填 | 不可以填 | distinct_id 是否是 login id,預設不是;注:匯入 json 格式數據不支援此參數,如需使用請在 json 數據中增加 "$is_login_id" 屬性。 | |
--event_from | -ef | 不可以填 | 和 event_default 選一個必填 | 不可以填 | 哪個欄位作為 event 名,如果指定,則每條數據的事件名為對應欄位的值。 |
--event_default | -ed | 不可以填 | 和 event_from 選一個必填 | 不可以填 | 預設的 event 名,如果指定,則將所有數據都算作這個 event 的。 |
--timestamp_from | -tf | 不可以填 | 選填 | 不可以填 | 哪個欄位作為 time, 如果指定,則每條數據對應的時間為對應欄位的值。 |
--timestamp_default | -td | 不可以填 | 選填 | 不可以填 | 預設的 timestamp, 如果指定,則將所有數據都算作這個時間的事件。 |
--timestamp_format | -tf | 不可以填 | 選填 | 不可以填 | 和 timestamp_from 一起使用,如果指定,並 timestamp_from 對應的欄位是個字串,可以透過這種方式指定時間格式。預設是%Y-%m-%d %H:%M:%S。 |
--item_type | 不可以填 | 不可以填 | 必填 | 匯入 item 數據時,指定 item_type 欄位的值 | |
--item_id | 不可以填 | 不可以填 | 必填 | 匯入 item 數據時,指定 item_id 欄位的值 |
4.5. 匯入 csv 格式的其他參數
參數名 | 别名 | 是否必填 | 解釋 |
---|---|---|---|
--filename | -f | 是 | csv檔案路徑 |
--property_list | -pl | 否 | 用逗號分割選取的 property, 舉例-p name,time 將會將 name 和 time 兩列作為 property 匯入。如果不填寫則表示全部作為 property 匯入。 |
--skip_identify | -i | 否 | 對應的列將不會做自動型別判斷,舉例--skip_identify name,id 將會將 name 和 id 不做型別判斷,完全作為 string 匯入如果不填寫則表示全部的選中列都會自動做型別判斷。 |
--ignore_value | 否 | 指定某些值為空,比如指定 --ignore_value null 則所有的null都被認為是空值 | |
--add_cname | -ac | 否 | 是否增加中文名,只對 event 有效. 如果 csv 的表頭是中文,程式會將對應的 property 名改為對應的拼音。這時,如果將 add_cname 選中,會自動在程式的最後把中英文的映射關係填上去,這樣在Ui上看到的對應 property 就是中文的了。 |
--web_url | -w | 如果選擇 add_cname 則必填 | web 連接的 url ,單機版類似 http://localhost:8007/, cloud 版類似 http://xxx.cloud.sensorsdata.cn。 |
--username | -u | 如果選擇 add_cname 則必填 | web 登入帳號。 |
--password | -p | 如果選擇 add_cname 則必填 | web 登入密碼。 |
--csv_delimiter | 否 | csv檔案的列分隔符號,預設為',',只接受單字元參數, 也可以傳\ + ascii的數字,比如\9表示是\t | |
--csv_quotechar | 否 | csv檔案的引用字元,用於指定csv字串的開始和結尾,預設為'"',只接受單字元參數, 也可以傳\ + ascii的數字,比如\9表示是\t | |
--csv_prefetch_lines | 否 | csv檔案預讀行數,預讀用於判斷列的類型,預設為-1,即預讀整個檔案。注意如果數據分佈不均(比如前幾行某個欄位沒有但是後面有)不要加這個參數 | |
--file_encoding | 否 | 設定 csv 檔案編碼格式,預設為 utf-8 |
4.6. 匯入 nginx log 的其他參數
參數名 | 別名 | 是否必填 | 解釋 |
---|---|---|---|
--filename | -f | 是 | nginx log 檔案路徑 |
--log_format | -F | 是 | nginx log 設定,類似'"$remote_addr" "$time_local" "$http_refer" "$status"'。 |
--property_list | -pl | 是 | 用逗號分割選取的 property, 舉例--property_list http_refer,status 將會將http_refer和status兩列作為 property 匯入。 |
--skip_identify | -i | 否 | 對應的列將不會做自動型別判斷,舉例--skip_identify request_user,status 將會將 request_user, status 不做型別判斷,完全作為 string 匯入。如果不填寫則表示全部的選中列都會自動做型別判斷。 |
--url_fields | -uf | 否 | 對應的列將作為url解析,用逗號分割。解析後會產生__<欄位名>_<解析內容>這樣命名的property,解析內容包括netloc, path, query, param_<參數名>。舉例對於$my_url欄位值為http://www.abc.com/path/to/mine?k1=v1&k2=2 ,會解析為{"__my_url_netloc ": "www.abc.com","__my_url_path ": "/path/to/mine", "__my_url_query ":"k1=v1&k2=v", "__my_url_param_k1 ": "v1","__my_url_param_k2 ":2}。注意可以再 property_list 設定這些欄位。預設是"http_referer"。 |
--filter_path | -fp | 否 | 過濾對應的 path ,可多選。這裡的 path 取的是 $request的path。支援正規。舉例--filter_path '.*\.gif' --filter_path '/index\.html' 將過濾對 gif 的請求和 index 的請求。 |
--ip_from | -if | 否 | 只對 event 有效, 哪個欄位作為 ip, 如果指定,則每條數據對應的 ip 為對應欄位的值, 預設是$remote_addr |
--ignore_value | 否 | 指定某些值為空,比如指定 --ignore_value null 則所有的null都被認為是空值 | |
--property_list_cnames | 否 | 用逗號分割property的對應名稱, 需要和--property_list一一對應 |
4.7. 匯入 mysql 數據的其他參數
参數名 | 别名 | 是否必填 | 解釋 |
---|---|---|---|
--user | -u | 是 | mysql 的 username |
--password | -p | 是 | mysql 的 password |
--host | -i | 是 | mysql 的網址 |
--port | -P | 是 | mysql 的埠號 |
--db | -d | 是 | mysql 對應的 db 名,一次只能指定一個 |
--sql | -q | 和 filename 選一個必填 | 查詢語句,建議加 order by 等方式確保多次查詢結果順序一致。 |
--filename | -f | 和 sql 選一個必填 | 查詢語句所在的檔案路徑,建議加 order by 等方式確保多次查詢結果順序一致。 |
--bool_property_list | -bp | 否 | 逗號分割的bool型別屬性列表,會將對應的屬性值為1的轉化為true,0轉化為false |
--case_sensitive | -cs | 否 | 匯入的屬性名是否是大小寫敏感,注意如果大小寫不敏感會全部轉化為大寫,預設為true |
4.8. 匯入 json log 的其他參數
參數名 | 别名 | 是否必填 | 解释 |
---|---|---|---|
--path | -p | 是 | log 的檔案/目錄路徑 |
注意匯入 json log,如果傳遞了 log 目錄,那麼會遍歷該目錄下一級的所有的檔案,並且按照字母順序匯入。本參數不支援嵌套目錄。
4.9. 匯入 oracle 數據的其他參數
参数名 | 别名 | 是否必填 | 解釋 |
---|---|---|---|
--user | -u | 是 | oracle 的 username |
--password | -p | 是 | oracle 的 password |
--dsn | -dsn | 是 | oracle 的 dsn |
--sql | -q | 和 filename 選一個必填 | 查詢語句,建議加 order by 等方式確保多次查詢結果順序一致。 |
--filename | -f | 和 sql 選一個必填 | 查詢語句所在的檔案路徑,建議加 order by 等方式確保多次查詢結果順序一致。 |
--bool_property_list | -bp | 否 | 逗號分割的 bool 型別屬性列表,會將對應的屬性值為 1 的轉化為 true,0 轉化為 false |
--case_sensitive | -cs | 否 | 匯入的屬性名是否是大小寫敏感,注意如果大小寫不敏感會全部轉化為大寫,預設為 false |
5. 常見文提
5.1. csv 的表頭是中文是否可以支援
根據我們在 數據格式 裡面的說明,property 的名稱是不可以包含中文的,但是可以設定 property 在 UI 上顯示為對應的中文名。透過設定 --add_cname 即可自動完成這一過程。使用上面的例子,buy.csv 格式如下:
用戶名,購買時間,商品id,商品名稱,商品類別
小明,2015-01-20 10:35:22,13579,真皮帽子 男士護耳保暖鴨舌皮帽平頂八角帽頭層牛皮帽子時尚休閒,男裝
小芳,2015-07-13 23:12:03,24680,官方正品ZINO 3D透亮無瑕BB霜SPF30PA++ 防曬遮瑕美白 小樣 3ml,護膚
小武,2015-04-03 20:30:01,31415,New Order Technique 2CD豪華版 歐版行貨 全新未拆,音像
匯入參數如下:
python3 format_importer.py csv_event \
--url 'http://localhost:8006/sa?project=xxx' \
--event_default 'UserBuy' \
--distinct_id_from '用戶名' \
--is_login \
--timestamp_from '購買時間' \
--filename 'buy.csv' \
--add_cname \
--web_url 'http://localhost:8007' \
--username admin \
--password password
注意在不同的平台上對編碼要求不同,需要確保預設編碼和檔案編碼一致,具體請參考 windows下使用說明。
5.2. 如何設定 nginx 可以過濾掉靜態檔案?
假設 nginx log 中包含了對 gif 檔案, css 檔案和 js 檔案的請求,這些請求希望過濾掉,可以使用 --filter_path 來過濾。
python3 format_importer.py nginx_event \
--filter_path '.*\.gif' \
--filter_path '.*\.css' \
--filter_path '.*\.js' \
# 其他參數。。。
5.3. 匯入了一半出錯了怎麼辦?
預設的情況下,出現解析錯誤的數據,匯入工具會在執行過程中對錯誤列印錯誤原因和錯誤的行數,然後丟棄錯誤數據繼續處理。列印 log 類似這樣的:
2015-10-28 14:58:52,020 808 WARNING failed to parse line 12
2015-10-28 14:58:52,021 809 WARNING Traceback (most recent call last):
File "format_importer.py", line 804, in main
sa.track(distinct_id, event, properties)
File "/Users/padme/git/sa2/tools/format_importer/sensorsanalytics/sdk.py", line 118, in track
data = self._normalize_data(data)
File "/Users/padme/git/sa2/tools/format_importer/sensorsanalytics/sdk.py", line 149, in _normalize_data
raise SensorsAnalyticsIllegalDataException("property [distinct_id] must not be empty")
sensorsanalytics.sdk.SensorsAnalyticsIllegalDataException: property [distinct_id] must not be empty
在執行結束的時候會列印讀取(total_read)了多少行,寫入(total_write)多少行,出錯(error)了多少行,跳過(skip)了多少行,類似這樣:
2015-10-28 14:58:52,023 618 INFO end import nginx
2015-10-28 14:58:52,024 838 INFO counter = {'error': 3, 'skip': 0, 'total': 300, 'total_read': 100, 'total_write': 97}.
如果希望能夠出錯就提示,可以增加選項 --quit_on_error,這樣的話出錯了的 log 如下:
2015-10-28 14:58:29,499 808 WARNING failed to parse line 12
2015-10-28 14:58:29,502 809 WARNING Traceback (most recent call last):
File "format_importer.py", line 804, in main
sa.track(distinct_id, event, properties)
File "/Users/padme/git/sa2/tools/format_importer/sensorsanalytics/sdk.py", line 118, in track
data = self._normalize_data(data)
File "/Users/padme/git/sa2/tools/format_importer/sensorsanalytics/sdk.py", line 149, in _normalize_data
raise SensorsAnalyticsIllegalDataException("property [distinct_id] must not be empty")
sensorsanalytics.sdk.SensorsAnalyticsIllegalDataException: property [distinct_id] must not be empty
2015-10-28 14:58:29,502 618 INFO end import nginx
2015-10-28 14:58:29,502 835 ERROR failed to import, please fix it and run with[--skip_cnt 11] again!
注意下方提示,說明已經成功匯入了11行,修復第12行的數據後在之前的命令上再加上參數 --skip_cnt 11 即可。
需要特別說明的是,對於 mysql,為了防止數據錯誤後不可恢復的問題,請務必確保 查詢sql多次呼叫結果一致,即:
沒有新數據再寫入,比如透過增加 WHERE 確保只匯入歷史數據。
查詢結果增加排序選項確保順序一致,比如增加 ORDER BY id。
5.4. 用 mysql 將兩張表 join 起來匯入,明明有數據為什麼提示我 distinct_id / timestamp / event 為空?
注意如果使用兩個表 join,列名要是唯一的,或要取別名。這裡的列名一方面是表示使用 distinct_id_from, timestamp_from, event_from 的參數,另一方面也是匯入後 property 的名字。
舉例,sql 如下:
SELECT a.uid, a.event, a.time, b.property1, b.property2 FROM a JOIN b ON a.action_id = b.action_id
那麼執行參數需要指定為
--distinct_id_from 'uid' \ --timestamp_from 'time' \ --event_from 'event'
匯入的 property 的名字也分別是(property1, property2) 而不是(b.property1, b.property2)。
如果列名不是唯一的,另一種方法是取別名. 舉例sql如下:
SELECT a.u AS uid, a.e AS event, a.t AS time, b.property AS property1, a.property AS property2 FROM a JOIN b ON a.action_id = b.action_id
那麼執行的參數指定為:
--distinct_id_from 'uid' \ --timestamp_from 'time' \ --event_from 'event'
匯入的 property 的名字也分別是(property1, property2)。
5.5. 用 mysql 匯入的時候,如何將數值轉化成文字/文字轉化成數值匯入?
mysql 的 CAST 方法支援型別轉化。
舉例,mysql 中有個型別為 int 的列 property1 和一個型別為 varchar(10) 的列為 property2,可以使用 sql:
SELECT CAST(property1 AS CHAR(10)) AS property1, CAST(property2 AS SIGNED) AS property2 FROM test_table;
將 property1 的值轉化成 10 個字元長的文字,將 property2 的值轉化為數值。
5.6. 如何匯入其他Project
如果沒有顯示指定 project,則預設匯入預設 project (default)。
可以透過 --url 裡面包含 project=<project_name> 來指定project 名,也可以透過 --project 參數來指定。如果同時指定則採用 --project 的參數。
注意,如果 --url 的值是透過右上角“帳號” -> “數據接入” -> “複製數據接收網址” 來取得的話,則複製的介面裡面自帶 project 參數,不需要額外指定。
此外,如果是匯入 json log,可以在 json 中增加 "project":"project名稱" 來使用一份數據匯入多個 project。log 裡面的 project 欄位優先級高於參數。
5.7. csv如何轉義
csv是用逗號分割的檔案格式,如果某一列的內容中包含逗號,需要用雙引號分割開,否則 format importer 將會報錯。舉例,csv 檔案內容如下:
col1,col2,col3 a,b,c,d
執行時將會報錯:
csv error near line 1: content has 1 more fields than header
即提示內容的列數比頭部的列數多一列。正確的做法是加上雙引號:
col1,col2,col3 a,"b,c",d
將會被識別為:
col1 | col2 | col3 |
a | b,c | d |
注意雙引號可以跨行。舉例,csv檔案內容如下:
col1,col2,col3 a,"b,c d,e",f
將會被識別為:
col1 | col2 | col3 |
a | b,c,d,e | f |
因此如果某一列以雙引號開頭,那麼csv會一直找到下一個雙引號結尾。如果兩個雙引號直接的字元過多,會報錯列超長:
_csv.Error: field larger than field limit (131072)
解決方法有兩個,一個是可以透過 --csv_quotechar 參數替換 csv 預設的字元串邊界符號,需要確保這個符號沒有出現過。另外就是對雙引號轉義,需要把一個雙引號變成兩個,並且對本列用雙引號引住。舉例,csv檔案內容如下:
col1,col2,col3 a,"""b",c
將會識別為
col1 | col2 | col3 |
a | "b | c |
5.8. 對於 json 格式的 log,使用 FormatImporter 匯入,和使用 LogAgent/BatchImporter匯入有什麼區別?
1. LogAgent 即時流式將 log 內容匯入,如果 log 在不斷更新,建議使用 LogAgent 匯入. 而 FormatImporter 和 BatchImporter 都是一次性匯入。
2. BatchImporter 在三者中匯入效率最高,但是只能在部署神策分析的電腦上使用。 FormatImporter , LogAgent 可以在任意電腦上執行。
5.9. windows下使用說明
在 windows 下使用 FormatImporter 時,由於終端的語法不同,預設編碼不同,有以下幾個注意事項:
1. 盡量使用設定檔案遞參數,而不是命令列傳遞,避免命令轉義。注意上述範例中的命令都是基於 unix 作業系統,如果直接在 windows 下面執行可能會出現語法錯誤或轉義。
2. csv 檔案預設支援 utf-8 編碼,如果出現編碼錯誤,可以先查看檔案編碼格式,然後使用 --file_encoding 命令設定編碼格式
3. 如果需要在 windows 下連接 mysql / oracle,需要對編碼做特殊處理,具體處理方式請諮詢神策技術支援同學。
5.10. 匯入限制
匯入數據時,formatImporter 匯入本身沒有數據量上限,但是如果匯入數據較大時,速度較慢,大約1 分鐘匯入500~700 條左右,且匯入的速度和網絡穩定性有關,如果匯入超時,可以使用內網數據接收網址嘗試是否可以。