本帖最后由 Ariy 于 2021-7-2 10:54 编辑
1.声明
本人咸鱼一枚,技术能力不如各位大佬,代码很渣,仅为给小服服主们分享一个运维+运营的思路,请互相尊重,谢谢!
2.开端
开服后,我们都会顶贴、发视频宣传自己的服务器,但是服务器人来人往,如何统计玩家在线时间、留存率等数据,是值得我们思考的问题。肯定有管理插件可以实现这样的功能,但是本人认为服务器插件表越清爽越好,非必要情况下不愿意加装插件,其实玩家加入游戏、退出游戏都有日志打印,那我们为什么不通过脚本从日志中获取到数据,供服主分析运维和运营情况呢?
3.实现
脚本首选语言python,不要问为啥。我们知道服务器日志是自动截断打包的(没有看到文档,有懂的大佬可以说一声),这里我们直接采用最暴力的方式,逐行读取整个文件,通过关键字获取到玩家登陆、登出等信息。复制代码 通过上述代码,我们逐行读取了日志文件,并且通过正则将每行日志拆解为时间、线程、日志级别、消息4个部份,如下面这样一条消息:
会被拆解为{timestamp:"10:00:01",thread:"Server thread",level:"INFO",msg:"运行时间: 3 天 12 小时 57 分钟"}。
另外我们知道,登陆时间的日志格式类似于:
这里我们同样采集比较暴力的in判断日志是否为登陆、登出日志,然后通过空格分割取到第一个元素即为用户名,再存到结果集中
复制代码 最后我们通过pymysql库将结果集存到mysql中,以供后续分析。因为我们每次读取日志都是全量读取,并不是增量读取的,所以我们要考虑重复数据的问题,这里我们直接把timestamp、key、value都作为键,并通过Mysql的ON DUPLICATE KEY UPDATE语法避免冲突。这一部分代码过于简单我们不再赘述。
4.分析
通过不断执行上述脚本,我们可以得到玩家的登陆和登出时间,那我们要怎么分析呢?我们首先通过pymysql来获取到指定日志的数据,暴力点的做法就是这样:
复制代码 然后我们可以遍历结果集进行分析,首先我们定义一个字典保存玩家登陆的时间,遍历中如果事件为登陆,则将登陆事件存到字典里面,如果事件为登出,则在登录字典中寻找,如果有,则时间相减即为玩家在线时间,如果没有,说明玩家前一天跨夜挂机,我们将登陆时间设定为当天0点。算出在线时间后,我们将在线时间存到结果集中。最后,我们会剩下一些登入时间,找不到对应登出事件,说明玩家跨夜挂机到第二天了,我们将这些登陆事件的登出时间设定为23:59:59,也存到结果集中。
复制代码 这样我们就得到了每个玩家的在线时间,可以排序得出玩家在线排名,也可以通过authme插件的注册日期来判断新玩家人数、新玩家游玩时间、3天内注册玩家留存率。复制代码 通过上述分析,我们可以得到像这样的数据:
同时,我们也可以用同样的方法标记出3日内注册的玩家,也可以通过插件的数据库来获取到玩家其他的数据,这里我们不再展开赘述。观察数据,我们可以看出服务器已经凉了,服主可以准备跑路了(划掉)。总之,这个数据是十分有意义的,服主可以对肝帝玩家做出激励,优先考虑长时间游玩的玩家的需求。同时,如果新玩家人数较少,我们可以通过扫描同类型服务器来判断到底是游戏的问题还是自己的问题(虽然我不会这样做)。最后,新玩家的游玩时间也是很重要的一个分析点,如果新玩家普遍游玩不到5分钟退服,那肯定在游戏设计上有一定问题,玩家既然看到宣传贴入服了,就说明宣传贴是符合胃口的,但是入服之后发现与预想不符合,那肯定服主需要做出改变。
5.展开
其实,日志中存在大量非常有用的服务器信息,比如"can't keep up!Is the server over load...."(服务器:危!),又比如我们可以定时执行gc命令,让日志中打印出区块、实体、掉落物、tps等信息。还有各种各样的插件事件都有对应的日志。
最后说一句:即使是快凉了的小破服,也要努力生存呀~与大家共勉。
1.声明
本人咸鱼一枚,技术能力不如各位大佬,代码很渣,仅为给小服服主们分享一个运维+运营的思路,请互相尊重,谢谢!
2.开端
开服后,我们都会顶贴、发视频宣传自己的服务器,但是服务器人来人往,如何统计玩家在线时间、留存率等数据,是值得我们思考的问题。肯定有管理插件可以实现这样的功能,但是本人认为服务器插件表越清爽越好,非必要情况下不愿意加装插件,其实玩家加入游戏、退出游戏都有日志打印,那我们为什么不通过脚本从日志中获取到数据,供服主分析运维和运营情况呢?
3.实现
脚本首选语言python,不要问为啥。我们知道服务器日志是自动截断打包的(没有看到文档,有懂的大佬可以说一声),这里我们直接采用最暴力的方式,逐行读取整个文件,通过关键字获取到玩家登陆、登出等信息。
- with open("/home/minecraft/skyblock/logs/latest.log") as f:
- for line in f.readlines():
- m = re.match("\[(?P<time>\d+:\d+:\d+)\] \[(?P<thread>[^/]+)/(?P<level>[A-Z]+)\]: (?P<msg>.*)", line)
[10:00:01] [Server thread/INFO]: 运行时间: 3 天 12 小时 57 分钟
会被拆解为{timestamp:"10:00:01",thread:"Server thread",level:"INFO",msg:"运行时间: 3 天 12 小时 57 分钟"}。
另外我们知道,登陆时间的日志格式类似于:
tianwc joined the gametianwc left the game
这里我们同样采集比较暴力的in判断日志是否为登陆、登出日志,然后通过空格分割取到第一个元素即为用户名,再存到结果集中
- if "logged in with entity id" in msg:
- res.append({'timestamp': timestamp, 'key': "login", 'value': msg.split(" ")[0]})
- if "left the game" in msg:
- res.append({'timestamp': timestamp, 'key': "logout", 'value': msg.split(" ")[0]})
4.分析
通过不断执行上述脚本,我们可以得到玩家的登陆和登出时间,那我们要怎么分析呢?我们首先通过pymysql来获取到指定日志的数据,暴力点的做法就是这样:
- select * from ariy.minecraft_data where timestamp like '%2021-07-01%';
- users = {}
- online = {}
- for item in data:
- if item[1] == 'login':
- users[item[2]] = item[0]
- cursor.execute("select * from authme.authme;")
- data = cursor.fetchall()
- user_login = {item[2]: item[10] for item in data}
- for item in sorted(online.items(), key=lambda item: item[1], reverse=True):
- print item[0], "在线", item[1], "分钟", "当日注册" if datetime.datetime.fromtimestamp(user_login[item[0]] / 1000).strftime("%Y-%m-%d") == ymd else ""
S*y 在线 1299 分钟
S*m 在线 805 分钟
x*u 在线 491 分钟
X*n 在线 486 分钟 当日注册
tianwc 在线 239 分钟
F*l 在线 201 分钟
Z*o 在线 153 分钟
g*e 在线 144 分钟
B*g 在线 49 分钟 当日注册
A*n 在线 39 分钟
l*n 在线 14 分钟
g*y 在线 9 分钟 当日注册
F*K 在线 4 分钟 当日注册
O*w 在线 1 分钟
M*n 在线 0 分钟 当日注册
l*3 在线 0 分钟
A*i 在线 0 分钟 当日注册
R*t 在线 0 分钟 当日注册
5.展开
其实,日志中存在大量非常有用的服务器信息,比如"can't keep up!Is the server over load...."(服务器:危!),又比如我们可以定时执行gc命令,让日志中打印出区块、实体、掉落物、tps等信息。还有各种各样的插件事件都有对应的日志。
最后说一句:即使是快凉了的小破服,也要努力生存呀~与大家共勉。
如果提高在线转换率 现在这个是个问题还有宣传
如何统计玩家在线时间、留存率等数据
我这边是通过插件记录玩家行为,判断这个玩家游戏模式以及常驻的概率
有点类似插件版那个同样是深度学习的插件,但我不太懂代码所以分不清哪个好
其实这种功能的插件应该出现几个,最好是能够联网统计信息的那种
大佬真厉害,我看不懂。。。
小冰糖a 发表于 2021-7-2 11:26
我这边是通过插件记录玩家行为,判断这个玩家游戏模式以及常驻的概率
有点类似插件版那个同样是深度学习的 ...
自研插件吗?如果已发布能不能分享一下,学习一下思路
是干货啊,厉害了
如果提高在线转换率 现在这个是个问题还有宣传