32. 게임 운영 Part 3: 플레이어 행동 로그

게임 서버에서 남기는 로그는 크게 1) 프로그램 디버깅을 위한 로그와 2) 고객 지원을 위해 남기는 사용자 행동 로그로 생각해볼 수 있습니다.

전자는 훨씬 더 양이 많고 굳이 DB 에 저장하지 않더라도 서버에 문제가 생겼을 때만 찾아볼 수 있으면 되지만, 후자는 상대적으로 양은 적지만 DB 와 같은 persistent storage 에 저장해야 합니다. 아이펀 엔진에서는 Debugging log 와 플레이어 activity log 두가지를 모두 지원합니다.

이 챕터는 플레이어 activity 로그에 대해서 설명합니다. 디버깅 로그에 관해서는 프로그래밍 Part1: 디버그용 로그 을 참고하세요.

32.1. Activity Logger Overview

로그로 남겨야 되는 게임 플레이어의 행동은 게임마다 다르기 때문에, 아이펀 엔진에서는 로그로 남길 행동을 JSON 파일로 기술하면 그 행동을 위한 Logger 함수를 생성해주는 방식을 사용합니다. 이제 프로그래머는 해당 Logger 를 이용해서 로그를 남깁니다. Activity log 는 프로그램 로그와는 별도로 MongoDB, JSON 파일 등으로 관리됩니다.

Tip

만일 iFun Deploy 위에서 게임을 돌리는 경우에 activity log 파일들을 수집해서 DB 에 저장해줍니다.

32.2. Activity logger 정의 파일

funapi_initiator my_project 라고 프로젝트를 만든 경우, src/my_project_loggers.json 이라는 이름으로 logger 를 정의하는 JSON 파일을 미리 만들어 줍니다.

이 파일 안에 다음과 같은 구조로 로그를 정의합니다.

{
  "LogType1": {
    "Argument1": "Type1"
  },

  "LogType2": {
    "Argument1": "Type1",
    "Argument2": "Type2"
  }
}

예를 들면 다음과 같은 방식으로 지정할 수 있습니다.

{
  "SessionOpened": {
    "session_id": "string",
    "when": "datetime2"
  },
  "SessionClosed": {
    "session_id": "string",
    "when": "datetime2"
  },
  "PlayerLoggedIn": {
    "session_id": "string",
    "account_id": "string",
    "when": "datetime2"
  },
  "PlayerDropItem": {
    "player_name": "string",
    "item_name": "string"
  }
}

32.2.1. Activity Logger 의 인자 type

Type 값으로 가능한 것들은 다음과 같은 것들이 있습니다.

Type Description
bool 참/거짓
double 실수형
integer 정수형
string 문자열형
datetime 날짜 타입 (time_t 형태)
datetime2 날짜 타입 (WallClock::Value 형태)

32.3. 자동 생성되는 Logger 함수

위와 같이 정의하고 compile 하면 자동으로 다음과 같은 Logger 함수가 생성됩니다.

namespace logger {

void SessionOpened(const string &session_id, const WallClock::Value &when);
void SessionClosed(const string &session_id, const WallClock::Value &when);
void PlayerLoggedIn(const string &session_id, const string &account_id, const WallClock::Value &when);
void PlayerDropItem(const string &player_name, const string &item_name);

}  // namespace logger

가령 플레이어가 아이템을 떨굴 때마다 이제 logger:PlayerItemDrop() 을 호출하면 됩니다.

class ActivityLog {

  public void SessionOpened(string arg_session_id, System.DateTime arg_when);
  public void SessionClosed(string arg_session_id, System.DateTime arg_when);
  public void PlayerLoggedIn(string arg_session_id, string arg_account_id, System.DateTime arg_when);
  public void PlayerLoggedIn(string arg_player_name, string arg_item_name);

}

가령 플레이어가 아이템을 떨굴 때마다 이제 ActivityLog.PlayerItemDrop() 을 호출하면 됩니다.

32.3.1. 인자의 타입과 프로그래밍 언어 타입 매칭

Activity logger 의 각 type 은 다음과 같이 프로그래밍 언어의 타입으로 매칭됩니다.

Logger type C++ type C# type
bool const bool bool
double const double double
integer const int64_t long
string const string & string
datetime time_t System.DateTime
datetime2 const WallClock::Value & System.DateTime

32.4. Activity logger 의 log 저장 위치

activity log 가 저장되는 위치는 MANIFEST.json 에서 설정합니다.

파일 형태나, DB 형태, Syslog 형태 등이 가능합니다.

다음은 MANIFEST.json 의 예제입니다.

"Logging": {
  "activity_log_output": "json://activity_log/test",
  "activity_log_rotation_interval": 60
}

위 예에서 activity_log_output 의 값에 따라 생성되는 log 의 위치가 달라집니다. 다음과 같은 것들이 가능합니다.

32.4.1. Standard I/O 로 출력

  • stdout: standard output 으로 log 를 출력합니다.
  • stderr: standard error 로 log 를 출력합니다.

32.4.2. 다른 logger 로 redirect

  • glog: Program log 가 생성하는 glog 에 같이 섞여서 출력합니다. (자세한 내용은 프로그래밍 Part1: 디버그용 로그 을 참고하세요.)
  • syslog://procname: syslog 의 INFO level 값으로 출력합니다. 이때 program name 으로 procname 을 쓰게 됩니다. 이 기능은 Linux 에서만 동작합니다.

32.4.3. 파일에 저장

  • file://path/to/filename: path/to/날짜 라는 디렉토리 아래에, filename.시간 형태로 파일을 만들고, 거기에 각 field 들 comma 로 구분해서 한줄씩 쓰게 됩니다.
  • json://path/to/file: file 의 경우와 유사한데 다만 comma 로 구분된 한줄 짜리 log 가 아니라, JSON 형태로 생성해줍니다.

Note

파일 형태의 경우는 log root 라는 특정 디렉토리 아래 생성되는데 이때의 규칙은 다음과 같습니다.

  • 개발 단계에서는 빌드 디렉토리 아래 activity_log/ 디렉토리 아래 생성됩니다.
  • 라이브 단계에서는 /var/log/funapi/{{ project_name }}/activity_log 아래 생성됩니다.

32.4.4. DB 에 저장

  • mongodb://user:passwd@host:port/database: MongoDB 의 특정 database 에 로그를 생성합니다. user, password, port 등의 정보는 선택적인 정보입니다. 예를 들어 mongodb://localhost:27017/my_activity_log 와 같은 형태가 될 수 있습니다. Replica set 지정등을 위한 보다 자세한 URI pattern 에 대해서는 MongoDB 연결 문자열 을 참고해주세요.

    MongoDB 에 로그를 남기기 위해서는 다음처럼 추가 패키지를 설치해주시기 바랍니다. MongoDB 서버를 설치하는 방법은 MongoDB 를 참고해주세요.

    • Ubuntu:

      sudo apt-get install libfunapi1-mongodblogger
      
    • CentOS:

      sudo yum install funapi1-mongodblogger
      

    또한, MANIFEST.jsonMongoDbBase 항목을 추가해야합니다.

    "Logging": {
      "activity_log_output": "mongodb://localhost:27017/activity_log",
    },
    "MongoDbBase": {
       "mongodb_logger_enable_ssl": false
    }
    

    Note

    SSL/TLS 연결이 필요한 경우 mongdb_logger_enable_ssl 옵션을 true 로 변경해야 합니다.

32.5. Activity Logger 기능 설정 파라미터

MANIFEST.json 의 Logging 섹션에 다음과 같은 설정을 지정할 수 있습니다.

  • activity_log_output: 액티비티 로그 저장 경로. 위에 설명된 대로 다음의 값들이 가능합니다.

    • stdout
    • stderr
    • glog
    • syslog://name
    • file://path/to/file
    • json://path/to/file
    • mongodb://user:passwd@host:port/database

    Note

    Syslog 는 Linux 에서만 동작합니다.

  • activity_log_rotation_interval: 액티비티 로그를 로테이션할 초단위 시간 주기. (type=int32, default=60)

  • activity_log_write_schema: 액티비티 로그에 스키마 정보도 출력할지 여부 (type=bool, default=true)