재화 변동 로그
- 현금성 재화와 비현금성 재화를 분리하여 각각 다른 카테고리로 지정하여 전송함
(예. 타이니팜의 경우 현금성(bell), 비현금성(gold)) - 게임 서버로 부터 유저 재화(캐시,게임머니 등)변동 로그를 수집하여 유저 게임 플레이 분석하고, 이를 통해 서비스 개선을 하기 위한 목적
카테고리¶
상용 서버 172.19.1.10 | noncash_var_log, cash_var_log |
---|---|
개발 서버 222.112.182.65 | test_noncash_var_log, test_cash_var_log |
로그 스펙¶
Note
스네이크 케이스(예: server_id
) 형태의 필드는 최종 저장소(BigQuery)에 저장될 때 카멜 케이스(예: serverId
) 형태로 변환되며, serverid
같은 스펙에 명시되지 않은 형태로 전송된 로그는 해당 컬럼에 저장되지 않습니다.
필드명 | 설명 | 타입 | 필수여부 |
---|---|---|---|
date | 로그 발생 시각, 형식: 년-월-일 시:분:초, 예) 2012-01-19 16:24:00 | string | Y |
channel | C2S: Hive KAK: 카카오 LIN: 라인 WEI: 웨이보 STE: 스팀 | string(3) | Y |
user_id | 클라이언트에서 보내온 허브 uid (타채널의 경우는 해당 채널에서 사용하는 user_id) | bigint | Y |
user_seq | 게임 서버 내에서 사용하는 유저계정 키값 (PK?) | bigint | N |
lang | 클라이언트에서 보내온 언어코드 ISO 639-2 (3 byte 언어 코드) 예)KOR | string(3) | Y |
game | 게임 브랜드 네임 사용 예) derbydays app_id의 세 번째 항목 com.com2us.littlelegends.kakao.freefull.apple.global.ios.universal → littlelegends | string(50) | Y |
market | 마켓 정보 "TS": SKT T store "OL": KT Olleh Market "OZ": LGU+ Oz Store "AP": Apple App store "GO": Google Play "SA": Samsung Apps "LE": Com2uS Lebi "MM": ChinaMobile Mobile Market "SN": Sina Weibo Point "36": Qihu 360 Point "MO": Momo Momo Point "DN": DeNA Mobage Point "NA": Naver App Store "AM": Amazon "ON": ONE store "FU": Funtap "HU": Huawei "OP": OPPO "VI": VIVO "XI": 샤오미 "TC": 텐센트 "HS": Hive Store(Crossplay) "ST": Steam | string(2) | Y |
level | 게임에서 유저의 레벨 | int | Y |
action_id | 게임에서 유니크한 재화 변동에 관한 유저의 액션 ID 범위: [1–(2^31−1)] 액션은 게임 상에서 api or protocol로 구분되는 것들로, 각 게임 서버에서는 액션에 대한 ID를 정의 해야 함. 한번 정의 후 변경되면 안됨. 반드시 테스트 필수!!! | int | Y |
action_name | action_id에 1:1 매핑되는 값으로, action_id가 다르다면 action_name도 달라야 함. 예) 밥주기, 농작물 수확 등 실 데이터는 action_id기반으로 쌓임 변경되면 메타테이블에 자동 반영됨 | string(50) | Y |
item_id | 재화 변동을 발생시킨 아이템 고유 식별자. 재화 변동 액션이 아이템과 연관이 없을 때는 0으로 표기. 범위: [0–(2^31−1)]1부터 시작하는 숫자값으로, 값이 없는 경우에만 0 해당 액션이 아이템과 연관이 있을 경우에 필요한 파라미터이며, 각 게임에서 유니크한 아이템의 ID를 정의해야 함 한번 정의 후 변경되면 안됨. 반드시 테스트 필수!!! | int | Y |
item_name | item_id와 1:1 매핑 되는 값 item_id가 0이 아닌 경우를 제외하고는 설명이 존재해야 함. item_id가 0인 경우는 0 item_id에 대한 알아보기 쉬운 간단한 설명 | string(50) | Y |
asset_id | 현금성 재화/소셜 포인트의 경우(1~100), 비현금성 재화의 경우 (101~) 한번 정의 후 변경되면 안됨. 반드시 테스트 필수!!! (cf. 현금 구매가능한 재화라 하더라도 구매 보다는 게임 내 획득이 주력인 재화인 경우는 101번 이상으로 세팅) | int | Y |
asset_name | asset_id에 대한 간단한 설명 예) bell, star, goldball, gold | string(50) | Y |
amount_prev | asset_id에 해당하는 재화의 변동 직전 재화량 | bigint | Y |
amount_var | asset_id에 해당하는 재화의 변동량. 재화 감소: 음수, 재화 증가: 양수 | bigint | Y |
amount_curr | asset_id에 해당하는 재화의 변동 직후 재화량. amount_curr = amount_prev + amount_var | int | Y |
amount_free_prev | asset_id에 해당하는 무상재화의 변동 직전 재화량 (일본 자금결제법 관련으로 추가) | bigint | Y (18.01.18) |
amount_free_var | asset_id에 해당하는 무상재화의 변동량. (일본 자금결제법 관련으로 추가) 재화 감소: 음수, 재화 증가: 양수 | bigint | Y (18.01.18) |
amount_free_curr | asset_id에 해당하는 무상재화의 변동 직후 재화량. (일본 자금결제법 관련으로 추가) br> amount_free_curr = amount_free_prev + amount_free_var | int | Y (18.01.18) |
amount_paid_prev | asset_id에 해당하는 유상재화의 변동 직전 재화량 (일본 자금결제법 관련으로 추가) | bigint | Y (18.01.18) |
amount_paid_var | asset_id에 해당하는 유상재화의 변동량. (일본 자금결제법 관련으로 추가) 재화 감소: 음수 재화 증가: 양수 | bigint | Y (18.01.18) |
amount_paid_curr | asset_id에 해당하는 유상재화의 변동 직후 재화량. (일본 자금결제법 관련으로 추가) amount_paid_curr = amount_paid_prev + amount_paid_var | int | Y (18.01.18) |
client_ip | 클라이언트의 IP, 이 값으로 GeoIP를 이용하여 country 값 추출 | string(32) | Y |
country | client_ip 를 못받아오는 경우 국가값을 직접 입력. 예) KR | string(2) | N |
server_ip | 서버의 IP | string(32) | Y |
company | 로그의 대상이 되는 게임 제작 회사: 예) "C2S": 컴투스, "GVI": 컴투스홀딩스 | string(3) | Y |
server_id | 서버 구분 코드 서버코드표 참조하여 '서버 코드(JSON 입력 코드)'를 입력 | string | Y |
is_emulator | 블루스택 등 PC용 에뮬레이터로 접속했으면 1, 아니면 0 PC버전으로 접속 시 2 | tinyint(1) | 필수는 아니지만 권장 |
game_language | 게임 언어. 2글자 소문자. 예) ko HIVE 식별자 정책 참고 | varchar | 필수는 아니지만 권장(18.01.18) |
account_id | 서버 내에서 고유한 계정 구분 값 (PK) | bigint | N (18.01.18) |
deviceid | HIVE did 값. 광고 식별자(Android AdvertisingID, iOS IDFA)를 추상화한 식별자 | bigint | N (18.01.18) |
guid | 매 로그마다 발생하는 고유 키 값 uuid와 같은 랜덤 문자열 형태를 권장 | varchar(64) | N |
real_count | 실제 소진한 재화 건수 예) 10개 일괄 수령 시 로그는 1개지만 실제 받은 재화는 10개 | int | Y (19.09.04) |
scribe 방식¶
<?php
$GLOBALS['THRIFT_ROOT'] = '/dev/scribe-php'; // 해당경로는 절대적인 것이 아님. 환경에 맞게 수정하기 바람.
include_once $GLOBALS['THRIFT_ROOT'].'/scribe.php';
include_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
include_once $GLOBALS['THRIFT_ROOT'].'/transport/TFramedTransport.php';
include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
…
public function writeCashVarLog(.....params.....) // 함수또한 예제임. 각자에 맞게 수정요함.(단 category는 반드시 현금성 재화는 ‘cash_var_log’로 맞춰야함.)
{
$msg['category'] = 'cash_var_log';
$msg['message'] = array();
$msg['message']['date'] = date('Y-m-d H:i:s', time());
$msg['message']['channel'] = $channel;
$msg['message']['user_id'] = $uid;
$msg['message']['country'] = $country;
$msg['message']['lang'] = $lang;
$msg['message']['game'] = $game;
$msg['message']['market'] = $market;
$msg['message']['level'] = $level;
$msg['message']['action_id'] = $action_id; // 한번 정의 후 변경 불가!!
$msg['message']['action_name'] = $action_name;
$msg['message']['item_id'] = $item_id; // 한번 정의 후 변경 불가!!
$msg['message']['item_name'] = $item_name;
$msg['message']['asset_id'] = $asset_id; // 각 게임모두 1~100 사이의 값을 사용할 것!!
$msg['message']['asset_name'] = $asset_name;
$msg['message']['amount_prev'] = $amount_prev;
$msg['message']['amount_var'] = $amount_var;
$msg['message']['amount_curr'] = $amount_curr;
$msg['message'] = json_encode($msg['message']);
$entry = new LogEntry($msg);
$messages = array($entry);
//var_dump($messages);
$socket = new TSocket('localhost', 1463, TRUE); // log를 전송할 목적지 host(포트고정)
$transport = new TFramedTransport($socket);
$protocol = new TBinaryProtocol($transport, FALSE, FALSE);
$scribe_client = new scribeClient($protocol, $protocol);
$transport->open();
$scribe_client->Log($messages);
$transport->close();
}
public function writeNonCashVarLog(.....params.....) // 함수또한 예제임. 각자에 맞게 수정요함.(단 category는 반드시 비현금성 재화는 ‘noncash_var_log’로 맞춰야함.)
{
$msg['category'] = 'noncash_var_log';
$msg['message'] = array();
$msg['message']['date'] = date('Y-m-d H:i:s', time());
$msg['message']['channel'] = $channel;
$msg['message']['user_id'] = $uid;
$msg['message']['country'] = $country;
$msg['message']['lang'] = $lang;
$msg['message']['game'] = $game;
$msg['message']['market'] = $market;
$msg['message']['level'] = $level;
$msg['message']['action_id'] = $action_id; // 한번 정의 후 변경 불가!!
$msg['message']['action_name'] = $action_name;
$msg['message']['item_id'] = $item_id; // 한번 정의 후 변경 불가!!
$msg['message']['item_name'] = $item_name;
$msg['message']['asset_id'] = $asset_id; // 각 게임모두 101 이상의 값을 사용할 것!!
$msg['message']['asset_name'] = $asset_name;
$msg['message']['amount_prev'] = $amount_prev;
$msg['message']['amount_var'] = $amount_var;
$msg['message']['amount_curr'] = $amount_curr;
$msg['message'] = json_encode($msg['message']);
$entry = new LogEntry($msg);
$messages = array($entry);
//var_dump($messages);
$socket = new TSocket('localhost', 1463, TRUE); // log를 전송할 목적지 host(포트고정)
$transport = new TFramedTransport($socket);
$protocol = new TBinaryProtocol($transport, FALSE, FALSE);
$scribe_client = new scribeClient($protocol, $protocol);
$transport->open();
$scribe_client->Log($messages);
$transport->close();
}
?>