update: 修复自打点属性重复上报问题, 调整了 iOS 桥接 NULL 判定, 尽量对齐 Flutter 项目还原 Android 项目的上报事件逻辑
Signed-off-by: huyufei <yufei.hu@castbox.fm>
parent
b186489a54
commit
cc5d36fea6
|
|
@ -451,7 +451,7 @@ namespace Guru.Editor
|
|||
string strMon = nowDate.Month.ToString("00");
|
||||
string strDay = nowDate.Day.ToString("00");
|
||||
string strQuarter = ((nowDate.Hour * 60 + nowDate.Minute) / 15).ToString("00");
|
||||
// 2024-08-01 08:00:00 to version string: 240801
|
||||
// 2024-08-01 08:00:00 to version string: 24080130
|
||||
string strBuildNumber = $"{strYear}{strMon}{strDay}{strQuarter}";
|
||||
return strBuildNumber;
|
||||
}
|
||||
|
|
@ -539,7 +539,7 @@ namespace Guru.Editor
|
|||
string strMon = nowDate.Month.ToString("00");
|
||||
string strDay = nowDate.Day.ToString("00");
|
||||
string strQuarter = ((nowDate.Hour * 60 + nowDate.Minute) / 15).ToString("00");
|
||||
// 2024-08-01 08:00:00 to version string: 240801
|
||||
// 2024-08-01 00:00:00 to version string: 24080100
|
||||
string strBuildNumber = $"{strYear}{strMon}{strDay}{strQuarter}";
|
||||
Debug.Log($"Get BuildVersion Code: {strBuildNumber}");
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,7 +1,7 @@
|
|||
// ==============================================
|
||||
// U3DAnalytics 1.12.0
|
||||
// Native Framework Version 0.3.6
|
||||
// update date: 2024-08-06 -- by HuYufei
|
||||
// update date: 2024-08-08 -- by HuYufei
|
||||
//
|
||||
// Created by HuYufei on 2022/11/17.
|
||||
// Copyright © 2022 guru. All rights reserved.
|
||||
|
|
@ -68,11 +68,15 @@ NSString * const TchError = @"tch_error";
|
|||
// 获取最终字符串
|
||||
+(char*) finalChar: (NSString *) string
|
||||
{
|
||||
if(string == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *tmpChar = [string cStringUsingEncoding:NSASCIIStringEncoding];
|
||||
|
||||
if (string == NULL)
|
||||
if(tmpChar == NULL){
|
||||
return NULL;
|
||||
|
||||
}
|
||||
char* res = (char*)malloc(strlen(tmpChar) + 1);
|
||||
strcpy(res, tmpChar);
|
||||
|
||||
|
|
@ -86,15 +90,16 @@ NSString * const TchError = @"tch_error";
|
|||
|
||||
// 设置是否启用日志错误上报
|
||||
+(void) setEnableErrorLog: (bool) value{
|
||||
if(enableErrorLog == false && value){
|
||||
|
||||
enableErrorLog = value;
|
||||
|
||||
if(value){
|
||||
// 注册事件
|
||||
enableErrorLog = true;
|
||||
[GuruAnalytics registerInternalEventObserverWithReportCallback:^(NSInteger code, NSString * info){
|
||||
[U3DAnalytics onEventCallback:code andInfo:info];
|
||||
}];
|
||||
|
||||
return;
|
||||
}
|
||||
// 否则只赋值
|
||||
enableErrorLog = value;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -108,29 +113,33 @@ NSString * const TchError = @"tch_error";
|
|||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 设置 BaseUrl
|
||||
+(void) setBaseUrl: (const char *) baseUrl{
|
||||
|
||||
if (baseUrl != nullptr && strlen(baseUrl) == 0) {
|
||||
return; // baseUrl 为空
|
||||
}
|
||||
|
||||
[GuruAnalytics setEventsUploadEndPointWithHost:[U3DAnalytics charToString:baseUrl]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 事件上报回调
|
||||
+(void) onEventCallback: (NSInteger)code andInfo:(NSString *) info{
|
||||
[U3DAnalytics sendMessage: [U3DAnalytics buildLogEventString: code andMessage:info]];
|
||||
+(void) onEventCallback: (NSInteger)code andInfo:(NSString *) info {
|
||||
if(enableErrorLog == false) {
|
||||
return; // 开关关闭不报
|
||||
}
|
||||
if(info == nil){
|
||||
return; // 空字符串不报
|
||||
}
|
||||
NSString *msg = [U3DAnalytics buildLogEventString: code andMessage:info];
|
||||
if(msg != NULL){
|
||||
return;
|
||||
}
|
||||
[U3DAnalytics sendMessageToUnity: msg];
|
||||
}
|
||||
|
||||
|
||||
// 构建数据
|
||||
+(NSString *) buildLogEventString: (NSInteger)status andMessage: (NSString *)msg{
|
||||
NSString *jsonString = [NSString stringWithFormat: @"{\"action\":\"logger_error\",\"data\":{\"code\":%d,\"msg\":\"%@\"}}", (int)status, msg];
|
||||
NSLog(@"[ANI][Error]: %@", jsonString);
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +167,7 @@ NSString * const TchError = @"tch_error";
|
|||
if([t isEqual: @"i"]){
|
||||
// int
|
||||
[dict setValue:@([v integerValue]) forKey:k];
|
||||
}else if([t isEqual: @"d"]){
|
||||
} else if ([t isEqual: @"d"]){
|
||||
// double
|
||||
[dict setValue:@([v doubleValue]) forKey:k];
|
||||
} else {
|
||||
|
|
@ -211,26 +220,31 @@ NSString * const TchError = @"tch_error";
|
|||
// 不存在 ad_paltform
|
||||
[U3DAnalytics onTchErrorEvent:@"no_ad_platform" andRaw:json andOther:@""];
|
||||
} else {
|
||||
if(![[_platform stringValue] isEqual:@"appstore"]){
|
||||
return;
|
||||
}
|
||||
|
||||
// 非IAP订单
|
||||
if(![[_platform stringValue] isEqual:@"appstore"] )
|
||||
{
|
||||
if([U3DAnalytics isNullObject: _value] ){
|
||||
if([U3DAnalytics isNullObject: _value] ){
|
||||
[dict setValue: [NSNumber numberWithDouble: targetValue] forKey:@"value"];
|
||||
[U3DAnalytics onTchErrorEvent:@"no_value" andRaw:json andOther:@""];
|
||||
} else {
|
||||
if([_value doubleValue] < targetValue){
|
||||
[dict setValue: [NSNumber numberWithDouble: targetValue] forKey:@"value"];
|
||||
[U3DAnalytics onTchErrorEvent:@"no_value" andRaw:json andOther:@""];
|
||||
} else {
|
||||
if([_value doubleValue] < targetValue){
|
||||
[dict setValue: [NSNumber numberWithDouble: targetValue] forKey:@"value"];
|
||||
[U3DAnalytics onTchErrorEvent:@"value_error"
|
||||
andRaw:json andOther: [_value stringValue]];
|
||||
}
|
||||
[U3DAnalytics onTchErrorEvent:@"value_error"
|
||||
andRaw:json andOther: [_value stringValue]];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 向Unity发送数据
|
||||
+(void) sendMessage: (NSString *)msg
|
||||
+(void) sendMessageToUnity: (NSString *)msg
|
||||
{
|
||||
if (msg == NULL) {
|
||||
return;
|
||||
}
|
||||
// NSLog(@"--- unityInitSDK222: %@:%@", gameObjectName, callbackName);
|
||||
if(gameObjectName != nil && callbackName != nil){
|
||||
char *t1 = [U3DAnalytics finalChar: gameObjectName];
|
||||
|
|
@ -277,7 +291,7 @@ NSString * const TchError = @"tch_error";
|
|||
|
||||
extern "C" {
|
||||
|
||||
// 请求GDPR
|
||||
// 初始化自打点
|
||||
void unityInitAnalytics(const char *appId, const char *deviceInfo, bool isDebug, const char *baseUrl, const char *uploadIpAddressStr)
|
||||
{
|
||||
// NSLog(@"--- [iOS] init Analytics libs");
|
||||
|
|
@ -297,6 +311,7 @@ extern "C" {
|
|||
// TODO: 当前的版本并不支持 uploadIpAddress, 后面的版本将 uploadIpAddressStr 转化为 Array<NSString> 传入接口
|
||||
}
|
||||
|
||||
// 初始化回调对象和参数
|
||||
void unityInitCallback(const char *gameObject, const char *method){
|
||||
// NSLog(@"--- unityInitSDK111: %s:%s", gameObject, method);
|
||||
gameObjectName = [NSString stringWithUTF8String:gameObject];
|
||||
|
|
@ -308,7 +323,7 @@ extern "C" {
|
|||
[GuruAnalytics setUserID:[U3DAnalytics charToString:uid]];
|
||||
}
|
||||
|
||||
// 设置用户ID
|
||||
// 设置Screen
|
||||
void unitySetScreen(const char *screenName){
|
||||
[GuruAnalytics setScreen:[U3DAnalytics charToString:screenName]];
|
||||
}
|
||||
|
|
@ -349,7 +364,7 @@ extern "C" {
|
|||
parameters:[U3DAnalytics buildDataWithJson:json andKey:evtName]]; // JSON转换
|
||||
}
|
||||
|
||||
// 上报事件
|
||||
// 设置 Tch02 的上限值(即将废弃)
|
||||
void unitySetTch02Value(const double value){
|
||||
[U3DAnalytics setTch02MaxValue:value];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// ReSharper disable ReplaceSubstringWithRangeIndexer
|
||||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
|
|
@ -78,14 +79,11 @@ namespace Guru
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误 code 表
|
||||
/// </summary>
|
||||
private readonly List<int> _errorCodeList = new List<int>();
|
||||
private bool _enableErrorLog;
|
||||
|
||||
private string _experimentGroupId;
|
||||
public string ExperimentGroupId => _experimentGroupId;
|
||||
private DateTime _lastReportTime;
|
||||
|
||||
/// <summary>
|
||||
/// 启动日志错误上报
|
||||
|
|
@ -145,6 +143,7 @@ namespace Guru
|
|||
// 初始化参数
|
||||
Agent.Init(appId, deviceInfo, baseUrl, uploadIpAddress, onInitComplete, isDebug);
|
||||
|
||||
_lastReportTime = new DateTime(1970, 1, 1);
|
||||
_isReady = true;
|
||||
Debug.Log($"{Tag} --- Guru Analytics [{Version}] initialized.");
|
||||
Debug.Log($"{Tag} --- GroupId: {groupId}");
|
||||
|
|
@ -403,7 +402,7 @@ namespace Guru
|
|||
{
|
||||
if (string.IsNullOrEmpty(raw)) return;
|
||||
if (!raw.Contains($"\"{ActionName}\"")) return; // 不对其他行为的日志进行过滤
|
||||
ParseWithJson(raw);
|
||||
ParseJsonAndSendEvent(raw);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -411,72 +410,64 @@ namespace Guru
|
|||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="errorInfo"></param>
|
||||
private void OnLoggerErrorEvent(int code, string errorInfo = "")
|
||||
/// <param name="category"></param>
|
||||
/// <param name="extra"></param>
|
||||
private void ReportDevAuditEvent(int code, string errorInfo = "", string category = "", Dictionary<string, object> extra = null)
|
||||
{
|
||||
// Debug.Log($"{Tag} --- OnLoggerErrorEvent: code:{code}\t info:{errorInfo}");
|
||||
|
||||
var codeString = ((AnalyticsCode)code).ToString();
|
||||
if (string.IsNullOrEmpty(codeString) || codeString == AnalyticsCode.Unknown.ToString()) codeString = $"ErrorCode:{code}";
|
||||
if (string.IsNullOrEmpty(codeString)) codeString = $"ErrorCode:{code}";
|
||||
if (string.IsNullOrEmpty(errorInfo)) errorInfo = "Empty";
|
||||
|
||||
Dictionary<string, dynamic> parameters = new Dictionary<string, dynamic>()
|
||||
var parameters = new Dictionary<string, dynamic>()
|
||||
{
|
||||
{"item_category", "error_event"},
|
||||
{"item_name", codeString},
|
||||
{"country", IPMConfig.IPM_COUNTRY_CODE},
|
||||
{"network", Application.internetReachability.ToString()},
|
||||
{"exp", _experimentGroupId}
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(category))
|
||||
{
|
||||
parameters[Analytics.ParameterItemCategory] = category;
|
||||
}
|
||||
|
||||
int len = 96;
|
||||
if (errorInfo.Length > len)
|
||||
errorInfo = errorInfo.TrimStart().Substring(0, len);
|
||||
|
||||
if (!string.IsNullOrEmpty(errorInfo))
|
||||
parameters["err"] = errorInfo;
|
||||
|
||||
if (extra != null)
|
||||
{
|
||||
// if (errorInfo.Contains("\"")) errorInfo = errorInfo.Replace("\"", "\\\"");
|
||||
|
||||
int len = 96;
|
||||
if (errorInfo.Length > len) errorInfo = errorInfo.TrimStart().Substring(0, len);
|
||||
foreach (var kvp in extra)
|
||||
{
|
||||
parameters[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorInfo = "empty error info";
|
||||
}
|
||||
|
||||
parameters["err"] = errorInfo;
|
||||
|
||||
Debug.Log($"{Tag} ------ ErrorLogInfo:: code:{codeString}\tinfo:{errorInfo}");
|
||||
|
||||
// Only for firebase GA
|
||||
Analytics.TrackEvent("dev_audit", parameters, new Analytics.EventSetting() { EnableFirebaseAnalytics = true });
|
||||
}
|
||||
|
||||
|
||||
private void ParseWithJson(string json)
|
||||
private void ParseJsonAndSendEvent(string json)
|
||||
{
|
||||
Debug.Log($"{Tag} ------ ParseWithJson: json:\n{json}");
|
||||
|
||||
int code = (int)AnalyticsCode.Unknown;
|
||||
int code = (int)AnalyticsCode.UNITY_INTERNAL_ERROR;
|
||||
string info = json;
|
||||
try
|
||||
{
|
||||
var dict = JsonConvert.DeserializeObject<JObject>(json);
|
||||
if(dict != null && dict.TryGetValue("data", out var jData))
|
||||
{
|
||||
var j = jData.Value<JObject>();
|
||||
if (j != null && j.TryGetValue("code", out var jCode))
|
||||
{
|
||||
code = jCode.Value<int>();
|
||||
|
||||
if (j.TryGetValue("msg", out var jMsg))
|
||||
{
|
||||
info = jMsg.Value<string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
info = $"wrong msg format: {json}";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info = "no data property";
|
||||
}
|
||||
ReportCodeInfo(code, info);
|
||||
if (dict == null || !dict.TryGetValue("data", out var jData)) return;
|
||||
var j = jData.Value<JObject>();
|
||||
if (j == null || !j.TryGetValue("code", out var jCode)) return;
|
||||
code = jCode.Value<int>();
|
||||
if (!j.TryGetValue("msg", out var jMsg)) return;
|
||||
info = jMsg.Value<string>();
|
||||
ReportWithCodeAndInfo(code, info);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
|
@ -487,85 +478,141 @@ namespace Guru
|
|||
// Debug.Log($"{Tag} --- {info}");
|
||||
Analytics.LogCrashlytics(json, false);
|
||||
Analytics.LogCrashlytics(info);
|
||||
ReportCodeInfo(code, info);
|
||||
ReportWithCodeAndInfo(code, info);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReportCodeInfo(int code, string info)
|
||||
/// <summary>
|
||||
/// 上报异常
|
||||
/// 上报条件:上报总数 > 30 条, 上报成功率小于 0.7, 且间隔 5 分钟
|
||||
/// Native 已经处理数量和成功率判断
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="info"></param>
|
||||
private void ReportWithCodeAndInfo(int code, string info)
|
||||
{
|
||||
if (Agent == null) return;
|
||||
if (Application.internetReachability == NetworkReachability.NotReachable) return; // 网络不可用时不上报
|
||||
|
||||
ReportAnalyticsAudit(); // 上报
|
||||
|
||||
// 源码:https://github.com/castbox/flutter_jigsort/blob/3.2.0V2/lib/data/jigsort_compliance_protocol.dart
|
||||
|
||||
var ac = (AnalyticsCode)code;
|
||||
Debug.Log($"{Tag} ------ Get Code And Info: code:{code}[{ac}] \tinfo:{info}");
|
||||
bool canCatch = false;
|
||||
switch (ac)
|
||||
{
|
||||
case AnalyticsCode.Unknown:
|
||||
case AnalyticsCode.DELETE_EXPIRED:
|
||||
case AnalyticsCode.UPLOAD_FAIL:
|
||||
case AnalyticsCode.NETWORK_LOST:
|
||||
case AnalyticsCode.CRONET_INIT_FAIL:
|
||||
case AnalyticsCode.CRONET_INIT_EXCEPTION:
|
||||
case AnalyticsCode.ERROR_API:
|
||||
case AnalyticsCode.ERROR_RESPONSE:
|
||||
case AnalyticsCode.ERROR_CACHE_CONTROL:
|
||||
case AnalyticsCode.ERROR_DELETE_EXPIRED:
|
||||
case AnalyticsCode.ERROR_LOAD_MARK:
|
||||
case AnalyticsCode.ERROR_DNS:
|
||||
case AnalyticsCode.ERROR_ZIP:
|
||||
case AnalyticsCode.ERROR_DNS_CACHE:
|
||||
case AnalyticsCode.CRONET_INTERCEPTOR:
|
||||
case AnalyticsCode.EVENT_LOOKUP:
|
||||
case AnalyticsCode.EVENT_SESSION_ACTIVE:
|
||||
canCatch = true;
|
||||
case AnalyticsCode.UNITY_INTERNAL_ERROR: // -1
|
||||
ReportUnityErrorEvent(code, info);
|
||||
break;
|
||||
// case AnalyticsCode.DELETE_EXPIRED:
|
||||
case AnalyticsCode.UPLOAD_FAIL: //14
|
||||
ReportUploadFailEvent(code, info);
|
||||
break;
|
||||
// case AnalyticsCode.NETWORK_LOST:
|
||||
// case AnalyticsCode.CRONET_INIT_FAIL:
|
||||
// case AnalyticsCode.CRONET_INIT_EXCEPTION:
|
||||
// case AnalyticsCode.ERROR_API:
|
||||
// case AnalyticsCode.ERROR_RESPONSE:
|
||||
// case AnalyticsCode.ERROR_CACHE_CONTROL:
|
||||
// case AnalyticsCode.ERROR_DELETE_EXPIRED:
|
||||
case AnalyticsCode.ERROR_LOAD_MARK: // 105
|
||||
ReportRuntimeErrorEvent(code, info);
|
||||
break;
|
||||
// case AnalyticsCode.ERROR_DNS:
|
||||
// case AnalyticsCode.ERROR_ZIP:
|
||||
// case AnalyticsCode.ERROR_DNS_CACHE:
|
||||
// case AnalyticsCode.CRONET_INTERCEPTOR:
|
||||
// case AnalyticsCode.ERROR_SESSION_START_ERROR:
|
||||
case AnalyticsCode.EVENT_LOOKUP: // 1003
|
||||
ReportDNSErrorEvent(code, info);
|
||||
break;
|
||||
case AnalyticsCode.EVENT_SESSION_ACTIVE: // 1004
|
||||
ReportSessionActiveErrorEvent(code, info);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!canCatch && code is > 100 and <= 200)
|
||||
{
|
||||
// 100 < code <= 200
|
||||
canCatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_errorCodeList != null && _errorCodeList.Count > 0)
|
||||
{
|
||||
if (_errorCodeList[0] == -1)
|
||||
{
|
||||
canCatch = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
canCatch = _errorCodeList.Contains(code);
|
||||
}
|
||||
}
|
||||
private int _reportUploadFailCount = 0;
|
||||
/// <summary>
|
||||
/// 上报失败事件 (14)
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="info"></param>
|
||||
private void ReportUploadFailEvent(int code, string info)
|
||||
{
|
||||
if (Agent.GetEventCountTotal() < 50) return; // 数量太少不报
|
||||
if ((float)Agent.GetEventCountUploaded() / Agent.GetEventCountTotal() > 0.6f) return; // 成功率太高也不报
|
||||
if (_reportUploadFailCount >= 5) return; // N 次之后不再上报
|
||||
ReportDevAuditEvent(code, info);
|
||||
_reportUploadFailCount++;
|
||||
}
|
||||
|
||||
if(canCatch) OnLoggerErrorEvent(code, info);
|
||||
private int _reportRuntimeExceptionTimes = 0;
|
||||
// 105
|
||||
private void ReportRuntimeErrorEvent(int code, string info)
|
||||
{
|
||||
if (_reportRuntimeExceptionTimes >= 5) return; // N 次之后不再上报
|
||||
ReportDevAuditEvent(code, info);
|
||||
_reportRuntimeExceptionTimes++;
|
||||
}
|
||||
|
||||
// 1003
|
||||
private void ReportDNSErrorEvent(int code, string info)
|
||||
{
|
||||
ReportDevAuditEvent(code, info, "ga_dns");
|
||||
}
|
||||
// 1004
|
||||
private void ReportSessionActiveErrorEvent(int code, string info)
|
||||
{
|
||||
ReportDevAuditEvent(code, info, "session_active");
|
||||
}
|
||||
// -1
|
||||
private void ReportUnityErrorEvent(int code, string info)
|
||||
{
|
||||
ReportDevAuditEvent(code, info, "unity");
|
||||
}
|
||||
|
||||
// 上报 Snapshot 数据
|
||||
private void ReportAnalyticsAudit()
|
||||
{
|
||||
if(DateTime.UtcNow - _lastReportTime < TimeSpan.FromMinutes(5)) // 5 分钟内只上报一次
|
||||
return;
|
||||
|
||||
var snapshot = Agent.GetAuditSnapshot();
|
||||
if (string.IsNullOrEmpty(snapshot)) return; // 空字段不报
|
||||
|
||||
var data = JsonParser.ToObject<Dictionary<string, object>>(snapshot);
|
||||
if (data == null) return; // 解析失败不报
|
||||
|
||||
// 上报事件
|
||||
ReportDevAuditEvent(0, "","analytics_audit", data);
|
||||
_lastReportTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UNIT_TEST
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public static void TestOnCallback(string msg)
|
||||
{
|
||||
Instance.OnSDKCallback(msg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 网络状态枚举
|
||||
/// 详见 guru_analytics 库 guru.core.analytics.handler.AnalyticsCode 类
|
||||
/// </summary>
|
||||
public enum AnalyticsCode
|
||||
{
|
||||
Unknown = -1,
|
||||
UNITY_INTERNAL_ERROR = -1, // unity 内部错误
|
||||
|
||||
DELETE_EXPIRED = 12, // 删除过期事件
|
||||
UPLOAD_FAIL = 14, // 上报事件失败
|
||||
|
|
@ -582,6 +629,7 @@ namespace Guru
|
|||
ERROR_ZIP = 107, // zip 错误
|
||||
ERROR_DNS_CACHE = 108, // zip 错误
|
||||
CRONET_INTERCEPTOR = 109, // cronet拦截器
|
||||
ERROR_SESSION_START_ERROR = 110,
|
||||
|
||||
EVENT_LOOKUP = 1003,
|
||||
EVENT_SESSION_ACTIVE = 1004,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ namespace Guru
|
|||
|
||||
/// <summary>
|
||||
/// 默认的本地配置
|
||||
/// 2024-08-08 经后台确认,只保留 B 组,C 组已经被废弃
|
||||
/// </summary>
|
||||
private const string DEFAULT_GURU_ANALYTICS_EXP = @"{
|
||||
""enable"": true,
|
||||
|
|
@ -76,12 +77,7 @@ namespace Guru
|
|||
""groupId"": ""B"",
|
||||
""baseUrl"": ""https://collect.saas.castbox.fm"",
|
||||
""uploadIpAddress"": [""13.248.248.135"", ""3.33.195.44""],
|
||||
""enableErrorLog"": true
|
||||
}, {
|
||||
""groupId"": ""C"",
|
||||
""baseUrl"": ""https://collect3.saas.castbox.fm"",
|
||||
""uploadIpAddress"": [""34.107.185.54""],
|
||||
""enableErrorLog"": true
|
||||
""enableErrorLog"": false
|
||||
}]
|
||||
}";
|
||||
|
||||
|
|
|
|||
|
|
@ -21,5 +21,8 @@ namespace Guru
|
|||
void ReportEventSuccessRate(); // 上报任务成功率
|
||||
void SetTch02Value(double value); // 设置太极02数值
|
||||
void InitCallback(string objName, string method); // 设置回调对象参数
|
||||
int GetEventCountTotal(); // 获取事件总数
|
||||
int GetEventCountUploaded(); // 获取成功上报的事件数量
|
||||
string GetAuditSnapshot(); // 获取 AuditSnapshot 字段
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ namespace Guru
|
|||
|
||||
#endif
|
||||
private static bool _isDebug = false;
|
||||
public static string BaseUrl = "";
|
||||
|
||||
#region 工具方法
|
||||
|
||||
|
|
@ -171,6 +170,11 @@ namespace Guru
|
|||
CallStatic("setEnableErrorLog", _enableErrorLog);
|
||||
}
|
||||
}
|
||||
|
||||
public int GetEventCountTotal() => CallStatic<int>("getEventCountAll");
|
||||
public int GetEventCountUploaded() => CallStatic<int>("getEventCountUploaded");
|
||||
public string GetAuditSnapshot() => CallStatic<string>("getAuditSnapshot");
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ namespace Guru
|
|||
[DllImport(K_INTERNAL)] private static extern void unitySetTch02Value(double value);
|
||||
[DllImport(K_INTERNAL)] private static extern void unitySetEnableErrorLog(bool value);
|
||||
[DllImport(K_INTERNAL)] private static extern void unityInitCallback(string objName, string method);
|
||||
[DllImport(K_INTERNAL)] private static extern int unityGetEventsCountAll();
|
||||
[DllImport(K_INTERNAL)] private static extern int unityGetEventsCountUploaded();
|
||||
#endif
|
||||
|
||||
private static bool _isDebug = false;
|
||||
|
|
@ -163,6 +165,29 @@ namespace Guru
|
|||
public static void TestCrashEvent()=> unityTestUnrecognizedSelectorCrash();
|
||||
#endif
|
||||
|
||||
public int GetEventCountTotal()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return unityGetEventsCountAll();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int GetEventCountUploaded()
|
||||
{
|
||||
#if UNITY_IOS
|
||||
return unityGetEventsCountUploaded();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public string GetAuditSnapshot()
|
||||
{
|
||||
// TODO:iOS 原生类并未实现此接口
|
||||
return "";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,12 @@ namespace Guru
|
|||
Debug.Log($"{TAG} EnableErrorLog:<color=orange>{value}</color>");
|
||||
_enableErrorLog = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int _eventTotalCount = 0;
|
||||
private int _eventSuccessCount = 0;
|
||||
|
||||
|
||||
public void Init(string appId, string deviceInfo, string baseUrl, string[] uploadIpAddress, Action onInitComplete, bool isDebug = false)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
|
|
@ -148,6 +151,12 @@ namespace Guru
|
|||
Debug.Log($"{TAG} LogEvent: GuruAnalytics:<color=orange>{eventName} ({priority})</color> Properties:\n{sb.ToString()}");
|
||||
}
|
||||
}
|
||||
|
||||
_eventTotalCount++;
|
||||
if (UnityEngine.Random.Range(0, 10) < 8)
|
||||
{
|
||||
_eventSuccessCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public void ReportEventSuccessRate()
|
||||
|
|
@ -160,6 +169,9 @@ namespace Guru
|
|||
Debug.Log($"{TAG} Tch02MaxValue: {value}");
|
||||
}
|
||||
|
||||
public int GetEventCountTotal() => _eventTotalCount;
|
||||
public int GetEventCountUploaded() => _eventSuccessCount;
|
||||
public string GetAuditSnapshot() => "";
|
||||
|
||||
#region Editor Test API
|
||||
|
||||
|
|
|
|||
|
|
@ -543,113 +543,112 @@ namespace Guru
|
|||
|
||||
//-------------------- 设置所有的属性 -----------------------
|
||||
|
||||
|
||||
public void ReportUid(string uid)
|
||||
{
|
||||
var prop = new MidWarePropertyUid(uid);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
public void ReportBLevel(string bLevel)
|
||||
{
|
||||
var prop = new MidWarePropertyBLevel(bLevel);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
public void ReportBPlay(string bPlay)
|
||||
{
|
||||
var prop = new MidWarePropertyBPlay(bPlay);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportAnalyticsExperimentGroup(string groupName)
|
||||
{
|
||||
var prop = new MidWarePropertyAnalyticsExperimentGroup(groupName);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportSignUpMethod(string methodName)
|
||||
{
|
||||
var prop = new MidWarePropertySignUpMethod(methodName);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportDeviceId(string deviceId)
|
||||
{
|
||||
var prop = new MidWarePropertyDeviceId(deviceId);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportFirstOpenTime(string firstOpenTime)
|
||||
{
|
||||
var prop = new MidWarePropertyFirstOpenTime(firstOpenTime);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportIsIapUser(bool isIapUser)
|
||||
{
|
||||
var prop = new MidWarePropertyIsIapUser(isIapUser);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportNetworkStatus(string networkStatus)
|
||||
{
|
||||
var prop = new MidWarePropertyNetwork(networkStatus);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportAdjustId(string adjustId)
|
||||
{
|
||||
var prop = new MidWarePropertyAdjustId(adjustId);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportAttStatus(string attStatus)
|
||||
{
|
||||
var prop = new MidWarePropertyAttStatus(attStatus);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportNotiPerm(string notiPerm)
|
||||
{
|
||||
var prop = new MidWarePropertyNotiPerm(notiPerm);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportAndroidId(string androidId)
|
||||
{
|
||||
var prop = new MidWarePropertyAndroidId(androidId);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportGoogleAdId(string googleAdId)
|
||||
{
|
||||
var prop = new MidWarePropertyGoogleAdId(googleAdId);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
public void ReportIDFV(string idfv)
|
||||
{
|
||||
var prop = new MidWarePropertyIDFV(idfv);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
public void ReportIDFA(string idfa)
|
||||
{
|
||||
var prop = new MidWarePropertyIDFA(idfa);
|
||||
_propertyMap.TryAdd(prop.key, prop);
|
||||
_propertyMap[prop.key] = prop;
|
||||
prop.Report();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue