# 调试模式

## 1. 适用场景

为了更加方便使用者调试代码和调整数据格式，我们为各个语言的 SDK 以及 LogAgent、BatchImporter 等导入工具，增加了调试模式的选项，主要用于：

1. 在开发人员调试代码和数据时使用；
2. 以同步、阻塞的方式，向后端发送数据；部分语言由于语言特性，这一机制可能略有不同；
3. 实时地展示服务端的校验结果，当校验失败时，不仅仅会展示具体的错误原因，并且会以抛异常等形式（具体实现取决于具体语言），显示地提醒使用者；
4. 对于校验成功的数据，在导入辅助工具中，可以实时看到最终入库的的各条数据的各个字段的值与类型。

请注意，*不要在生产环境或正式发布的 App 中使用 Debug 模式*。

## 2. 使用

### 2.1 SDK 使用调试模式

各个语言的 SDK 使用调试模式，主要是在初始化时，加上相关的参数。由于不同语言的实现机制不同，我们分别进行说明。

#### 2.1.1 Python SDK

在 Python SDK 中，使用调试模式，需要初始化一个专门的 DebugConsumer 对象，然后用这个 DebugConsumer 对象来初始化对应的 SensorsAnalytics 对象。

DebugConsumer 的构造函数的定义如下：

```python
def __init__(self, url_prefix, write_data=True, request_timeout=None):
        """
        初始化Consumer
        :param url_prefix: 神策分析用于数据接收的 URL
        :param write_data: 发送过去的数据是真正写入，还是仅仅进行检查
        :param request_timeout:请求的超时时间,单位毫秒
        :return:
        """
```

各个参数含义在注释上已经写明了。特别需要强调几点：

1. url\_prefix：该参数与其他 Consumer 一样，为神策分析用于数据接收的 URL
2. write\_data：这个参数默认为 `True`，也即发送过去的数据会真正地写入后端；如果这个参数设置为 `False`，则说明数据只发送过去进行校验，不会真正地写入。

#### 2.1.2 PHP SDK

PHP SDK 的调试模式的使用方式和 Python SDK 类似，也是构造一个 DebugConsumer 的对象，然后用它来初始化 SensorsAnalytics 对象。

DebugConsumer 的构造函数如下：

```php
    /**
     * DebugConsumer constructor,用于调试模式.
     * 具体说明可以参照: http://www.sensorsdata.cn/manual/debug_mode.html
     * 
     * @param string $url_prefix 神策分析用于数据接收的 URL
     * @param bool $write_data 是否把发送的数据真正写入
     * @param int $request_timeout 请求服务器的超时时间,单位毫秒.
     * @throws SensorsAnalyticsDebugException
     */
    public function __construct($url_prefix, $write_data = True, $request_timeout = 1000)
```

各个参数的含义与 Phthon SDK 基本一致，不再赘述。

#### 2.1.3 Java SDK

在 Java SDK 中使用调试模式，需要初始化一个专门的 DebugConsumer 对象，然后用这个 DebugConsumer 对象来初始化对应的 SensorsAnalytics 对象。DebugConsumer 的构造函数的定义如下：

```java
    /**
     * DebugConsumer，用于调试模式
     *
     * @param serverUrl 神策分析采集数据的 URL
     * @param writeData 是否把发送的数据真正写入神策分析
     */
    public DebugConsumer(final String serverUrl, final boolean writeData)
```

各个参数的含义与 Phthon SDK 基本一致，不再赘述。

#### 2.1.4 iOS SDK

iOS SDK 提供 Debug 模式，用于校验数据导入，用户使用时，请小心该设置，不要带到正式发布的 App 中。它将可能影响用户体验。

使用 SDK 版本高于 1.10.22 用户，可以使用「调试模式动态配置」进行调试模式的配置 [查看使用说明](https://54td.gitbook.io/shence/technical_guide/data_import/debug_mode/set_debug_mode)

iOS SDK 中通过 `SensorsAnalyticsSDK` 的参数初始化，指定 Debug 模式:

```
/**
 * @abstract
 * 根据传入的所部署的 SensorsAnalytics 服务器的 URL，返回一个<code>SensorsAnalyticsSDK</code>的单例
 *
 * @param serverURL 神策分析用数据接收的 URL
 * @param launchOptions launchOptions
 * @param debugMode 是否打开 Debug 模式
 *
 * @return 返回的单例
 */
+ (SensorsAnalyticsSDK *)sharedInstanceWithServerURL:(nonnull NSString *)serverURL
                                        andLaunchOptions:(NSDictionary * _Nullable)launchOptions
                                        andDebugMode:(SensorsAnalyticsDebugMode)debugMode;
```

其中 `SensorsAnalyticsDebugMode` 为枚举类型，定义如下:

```
/**
 * @abstract
 * Debug 模式，用于检验数据导入是否正确。该模式下，事件会逐条实时发送到 SensorsAnalytics，并根据返回值检查
 * 数据导入是否正确。
 *
 * @discussion
 * Debug 模式的具体使用方式，请参考:
 *  http://www.sensorsdata.cn/manual/debug_mode.html
 *
 * Debug 模式有三种选项:
 *   SensorsAnalyticsDebugModeOff - 关闭 DEBUG 模式
 *   DebugOnly - 打开 DEBUG 模式，但该模式下发送的数据仅用于调试，不进行数据导入
 *   DebugAndTrack - 打开 DEBUG 模式，并将数据导入到 SensorsAnalytics 中
 */
typedef NS_ENUM(NSInteger, SensorsAnalyticsDebugMode) {
    SensorsAnalyticsDebugOff,
    SensorsAnalyticsDebugOnly,
    SensorsAnalyticsDebugAndTrack,
};
```

`SensorsAnalyticsDebugOnly` 模式下，数据不会真正写入后端，只用于调试数据导入。 `SensorsAnalyticsDebugAndTrack` 下，数据不仅用于调试，也会真正导入后端。

一个使用 Debug 模式初始化 `SensorsAnalyticsSDK` 的样例如下：

```
    [SensorsAnalyticsSDK sharedInstanceWithServerURL:@"http://sa_host:8006/sa"
                                        andLaunchOptions:launchOptions
                                        andDebugMode:SensorsAnalyticsDebugOnly];
```

它初始化 `SensorsAnalyticsSDK` 实例，并定义 Debug 模式为 `SensorsAnalyticsDebugOnly`，校验埋点的事件，但事件不会真正导入后端。

#### 2.1.5 Android SDK

Android SDK 提供 Debug 模式，用于校验数据导入，用户使用时，请小心该设置，不要带到正式发布的 App 中。它将可能影响用户体验。

使用 SDK 版本高于 3.0.3 用户，可以使用「调试模式动态配置」进行调试模式的配置 [查看使用说明](https://54td.gitbook.io/shence/technical_guide/data_import/debug_mode/set_debug_mode)

Android SDK 的调试模式在 `SensorsDataAPI` 实例初始化时设置，`SensorsDataAPI`初始化有五个参数，最后一个 `debugMode` 用于指定 Debug 模式的类型，其中 DebugMode 为枚举类型，初始化方法和 DebugMode 的定义如下

```java
public class SensorsDataAPI {

  /**
   * Debug 模式，用于检验数据导入是否正确。该模式下，事件会逐条实时发送到 SensorsAnalytics，并根据返回值检查
   * 数据导入是否正确。
   * <p/>
   * Debug 模式的具体使用方式，请参考:
   * http://www.sensorsdata.cn/manual/debug_mode.html
   * <p/>
   * Debug 模式有三种：
   * DEBUG_OFF - 关闭 DEBUG 模式
   * DEBUG_ONLY - 打开 DEBUG 模式，但该模式下发送的数据仅用于调试，不进行数据导入
   * DEBUG_AND_TRACK - 打开 DEBUG 模式，并将数据导入到 SensorsAnalytics 中
   */
  public enum DebugMode {
    DEBUG_OFF(false, false),
    DEBUG_ONLY(true, false),
    DEBUG_AND_TRACK(true, true);
    // ...
  }

  /**
   * 初始化并获取 SensorsDataAPI 单例
   *
   * @param context App 的Context
   * @param serverURL 神策分析用于收集事件的服务地址
   * @param debugMode Debug 模式
   *
   * @return an instance of SensorsDataAPI associated with your project
   */
  public static SensorsDataAPI sharedInstance(Context context, String serverURL,
      DebugMode debugMode) {
    // ...
  }

  // ...
}
```

当 Debug 模式设为 `DEBUG_ONLY` 时，数据不会真正写入后端，只用于调试数据导入。 当 Debug 模式设置为`DEBUG_AND_TRACK` 时，数据不仅用于调试，也会真正导入后端。

一个使用 Debug 模式初始化 `SensorsDataAPI` 的样例如下：

```java
SensorsDataAPI sa = SensorsDataAPI.sharedInstance(
          this,
          "http://sa_host:8006/sa",
          SensorsDataAPI.DebugMode.DEBUG_ONLY);
```

它初始化 `SensorsDataAPI` 实例，并定义 Debug 模式为 `DEBUG_ONLY`，校验埋点的事件，但事件不会真正导入后端。

### 2.2 LogAgent 和 BatchImporter 使用调试模式

LogAgent 和 BatchImporter 的调试模式主要是对数据正确性的校验，详情请参考：

* [BatchImporter 使用说明](https://54td.gitbook.io/shence/technical_guide/import_tool/batch_importer) 中 4.2.校验数据模式
* [LogAgent 使用说明](https://54td.gitbook.io/shence/technical_guide/import_tool/log_agent) 中 5.使用 LogAgent 校验数据
* [FormatImporter 使用说明](https://54td.gitbook.io/shence/technical_guide/import_tool/format_importer) 中 4.2.公共参数
