콘텐츠로 이동

재화 변동 로그

  • 현금성 재화와 비현금성 재화를 분리하여 각각 다른 카테고리로 지정하여 전송함
    (예. 타이니팜의 경우 현금성(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에 해당하는 <span sytle="color: #0055FF"무상재화의 변동 직전 재화량
(일본 자금결제법 관련으로 추가)
bigint Y (18.01.18)
amount_free_var asset_id에 해당하는 <span sytle="color: #0055FF"무상재화의 변동량.
(일본 자금결제법 관련으로 추가)
재화 감소: 음수, 재화 증가: 양수
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에 해당하는 <span sytle="color: #FF3300"유상재화의 변동 직전 재화량
(일본 자금결제법 관련으로 추가)
bigint Y (18.01.18)
amount_paid_var asset_id에 해당하는 <span sytle="color: #FF3300"유상재화의 변동량.
(일본 자금결제법 관련으로 추가)
재화 감소: 음수
재화 증가: 양수
bigint Y (18.01.18)
amount_paid_curr asset_id에 해당하는 <span sytle="color: #FF3300"유상재화의 변동 직후 재화량.
(일본 자금결제법 관련으로 추가)
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();  
}
?>

활용 예시

  • 재화별 지급/회수 현황을 파악하고 지급량 대비 회수율 확인합니다. 회수율이 낮을 경우 매출에 영향을 미칩니다.
  • 게임에서 유저의 행동(Action)과 이를 통해 얻는 아이템(Item) 종류를 구분해 지급/회수가 원활한 곳을 확인합니다.
  • 추가 아이템 판매나 무료로 제공한 이벤트 재화 수집 정도 등 상세 내역을 확인할 수 있습니다.
  • 작업 전 Asset/Action/Item으로 구분해서 정의합니다. (PM, 플랫폼기획, BI기획 협의)