Skip to content

Commit

Permalink
Merge pull request #22 from DeNA/custom-reporters
Browse files Browse the repository at this point in the history
Introduce customizable reporters
  • Loading branch information
Kuniwak authored Nov 17, 2023
2 parents 4d493bb + ec9d2bf commit be92c72
Show file tree
Hide file tree
Showing 27 changed files with 785 additions and 327 deletions.
22 changes: 19 additions & 3 deletions Editor/Localization/ja.po
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ msgstr "JUnitレポート出力パス"
msgid "JUnit report output path"
msgstr "JUnit形式のレポートファイル出力パス(省略時は出力されない)"

# reporter
msgid "Reporter"
msgstr "レポータ"

# reporter tooltip
msgid "Reporter that called when some errors occurred in target application"
msgstr "対象のアプリケーションで発生したエラーを通知するレポータ"

# obsolete slack settings
msgid "Slack settings will be moved to SlackReporter"
msgstr "Slack 設定は SlackReporter へ移動しました"

# slackToken
msgid "Slack Token"
msgstr "Slackトークン"
Expand All @@ -108,19 +120,19 @@ msgid "Slack Mention Settings"
msgstr "Slackメンション設定"

# mentionSubTeamIDs
msgid "Mention Sub Team IDs"
msgid "Sub Team IDs to Mention"
msgstr "メンション宛先"

# mentionSubTeamIDs tooltip
msgid "Mention to sub team ID (comma separates)"
msgid "Sub team IDs to mention (comma separates)"
msgstr "Slack通知メッセージでメンションするチームのIDをカンマ区切りで指定します"

# addHereInSlackMessage
msgid "Add @here Into Slack Message"
msgstr "@hereをメッセージにつける"

# addHereInSlackMessage tooltip
msgid "Add @here into Slack message"
msgid "Whether adding @here into Slack messages or not"
msgstr "Slack通知メッセージに@hereを付けます"

# Header: Error Handling Settings
Expand Down Expand Up @@ -320,3 +332,7 @@ msgstr "操作を記録したJSONファイル"
# recordedJson tooltip
msgid "JSON file recorded by AutomatedQA package"
msgstr "Automated QAパッケージのRecorded Playbackウィンドウで記録したjsonファイルを設定します"

# composite reporters
msgid "Reporters"
msgstr "レポータ"
3 changes: 3 additions & 0 deletions Editor/UI/Reporters.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions Editor/UI/Reporters/CompositeReporterEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) 2023 DeNA Co., Ltd.
// This software is released under the MIT License.

using DeNA.Anjin.Reporters;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace DeNA.Anjin.Editor.UI.Reporters
{
/// <summary>
/// Editor for <c cref="CompositeReporter" />
/// </summary>
[CustomEditor(typeof(CompositeReporter))]
public class CompositeReporterEditor : UnityEditor.Editor
{
private SerializedProperty _reportersProp;
private ReorderableList _reorderableList;
private static readonly string s_reporters = L10n.Tr("Reporters");
private GUIContent _reportersGUIContent;
private static readonly string s_reporter = L10n.Tr("Reporter");
private GUIContent _reporterGUIContent;


private void OnEnable()
{
Initialize();
}


private void Initialize()
{
_reportersProp = serializedObject.FindProperty(nameof(CompositeReporter.reporters));
_reportersGUIContent = new GUIContent(s_reporters);
_reporterGUIContent = new GUIContent(s_reporter);
_reorderableList = new ReorderableList(serializedObject, _reportersProp)
{
drawHeaderCallback = rect => EditorGUI.LabelField(rect, _reportersGUIContent),
elementHeightCallback = _ => EditorGUIUtility.singleLineHeight,
// XXX: Dont use discarded parameter to treat Unity 2019.x
// ReSharper disable UnusedParameter.Local
drawElementCallback = (rect, index, active, focused) =>
// ReSharper restore UnusedParameter.Local
{
var elemProp = _reportersProp.GetArrayElementAtIndex(index);
EditorGUI.PropertyField(rect, elemProp, _reporterGUIContent);
}
};
}


public override void OnInspectorGUI()
{
serializedObject.Update();

_reorderableList.DoLayoutList();

serializedObject.ApplyModifiedProperties();
}
}
}
3 changes: 3 additions & 0 deletions Editor/UI/Reporters/CompositeReporterEditor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 81 additions & 0 deletions Editor/UI/Reporters/SlackReporterEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) 2023 DeNA Co., Ltd.
// This software is released under the MIT License.

using DeNA.Anjin.Reporters;
using UnityEditor;
using UnityEngine;

namespace DeNA.Anjin.Editor.UI.Reporters
{
/// <summary>
/// Editor for <c cref="SlackReporter" />
/// </summary>
[CustomEditor(typeof(SlackReporter))]
public class SlackReporterEditor : UnityEditor.Editor
{
private const float SpacerPixels = 10f;
private const float SpacerPixelsUnderHeader = 4f;

private static readonly string s_slackToken = L10n.Tr("Slack Token");
private static readonly string s_slackTokenTooltip = L10n.Tr("Slack API token");
private SerializedProperty _slackTokenProp;
private GUIContent _slackTokenGUIContent;

private static readonly string s_slackChannels = L10n.Tr("Slack Channels");
private static readonly string s_slackChannelsTooltip = L10n.Tr("Slack channels to send notification");
private SerializedProperty _slackChannelsProp;
private GUIContent _slackChannelsGUIContent;

private static readonly string s_slackMentionSettingsHeader = L10n.Tr("Slack Mention Settings");

private static readonly string s_mentionSubTeamIDs = L10n.Tr("Sub Team IDs to Mention");
private static readonly string s_mentionSubTeamIDsTooltip = L10n.Tr("Sub team IDs to mention (comma separates)");
private SerializedProperty _mentionSubTeamIDsProp;
private GUIContent _mentionSubTeamIDsGUIContent;

private static readonly string s_addHereInSlackMessage = L10n.Tr("Add @here Into Slack Message");
private static readonly string s_addHereInSlackMessageTooltip = L10n.Tr("Whether adding @here into Slack messages or not");
private SerializedProperty _addHereInSlackMessageProp;
private GUIContent _addHereInSlackMessageGUIContent;


private void OnEnable()
{
Initialize();
}


private void Initialize()
{
_slackTokenProp = serializedObject.FindProperty(nameof(SlackReporter.slackToken));
_slackTokenGUIContent = new GUIContent(s_slackToken, s_slackTokenTooltip);

_slackChannelsProp = serializedObject.FindProperty(nameof(SlackReporter.slackChannels));
_slackChannelsGUIContent = new GUIContent(s_slackChannels, s_slackChannelsTooltip);

_mentionSubTeamIDsProp = serializedObject.FindProperty(nameof(SlackReporter.mentionSubTeamIDs));
_mentionSubTeamIDsGUIContent = new GUIContent(s_mentionSubTeamIDs, s_mentionSubTeamIDsTooltip);

_addHereInSlackMessageProp = serializedObject.FindProperty(nameof(SlackReporter.addHereInSlackMessage));
_addHereInSlackMessageGUIContent = new GUIContent(s_addHereInSlackMessage, s_addHereInSlackMessageTooltip);
}


public override void OnInspectorGUI()
{
serializedObject.Update();

EditorGUILayout.PropertyField(_slackTokenProp, _slackTokenGUIContent);
EditorGUILayout.PropertyField(_slackChannelsProp, _slackChannelsGUIContent);

GUILayout.Space(SpacerPixels);
GUILayout.Label(s_slackMentionSettingsHeader);
GUILayout.Space(SpacerPixelsUnderHeader);

EditorGUILayout.PropertyField(_mentionSubTeamIDsProp, _mentionSubTeamIDsGUIContent);
EditorGUILayout.PropertyField(_addHereInSlackMessageProp, _addHereInSlackMessageGUIContent);

serializedObject.ApplyModifiedProperties();
}
}
}
3 changes: 3 additions & 0 deletions Editor/UI/Reporters/SlackReporterEditor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions Editor/UI/Settings/AutopilotSettingsEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,19 @@ public class AutopilotSettingsEditor : UnityEditor.Editor

private static readonly string s_junitReportPath = L10n.Tr("JUnit Report Path");
private static readonly string s_junitReportPathTooltip = L10n.Tr("JUnit report output path");
private static readonly string s_reporter = L10n.Tr("Reporter");
private static readonly string s_reporterTooltip = L10n.Tr("Reporter that called when some errors occurred in target application");

private static readonly string s_slackToken = L10n.Tr("Slack Token");
private static readonly string s_slackTokenTooltip = L10n.Tr("Slack API token");
private static readonly string s_slackChannels = L10n.Tr("Slack Channels");
private static readonly string s_slackChannelsTooltip = L10n.Tr("Slack channels to send notification");

private static readonly string s_slackMentionSettingsHeader = L10n.Tr("Slack Mention Settings");
private static readonly string s_mentionSubTeamIDs = L10n.Tr("Mention Sub Team IDs");
private static readonly string s_mentionSubTeamIDsTooltip = L10n.Tr("Mention to sub team ID (comma separates)");
private static readonly string s_mentionSubTeamIDs = L10n.Tr("Sub Team IDs to Mention");
private static readonly string s_mentionSubTeamIDsTooltip = L10n.Tr("Sub team IDs to mention (comma separates)");
private static readonly string s_addHereInSlackMessage = L10n.Tr("Add @here Into Slack Message");
private static readonly string s_addHereInSlackMessageTooltip = L10n.Tr("Add @here into Slack message");
private static readonly string s_addHereInSlackMessageTooltip = L10n.Tr("Whether adding @here into Slack messages or not");

private static readonly string s_errorHandlingSettingsHeader = L10n.Tr("Error Handling Settings");
private static readonly string s_handleException = L10n.Tr("Handle Exception");
Expand All @@ -64,6 +67,9 @@ public class AutopilotSettingsEditor : UnityEditor.Editor
private static readonly string s_handleWarningTooltip = L10n.Tr("Notify when Warning detected in log");
private static readonly string s_ignoreMessages = L10n.Tr("Ignore Messages");

private static readonly string s_obsoletedSlackParamsHelpBox =
L10n.Tr("Slack settings will be moved to SlackReporter");

private static readonly string s_ignoreMessagesTooltip =
L10n.Tr("Do not send notifications when log messages contain this string");

Expand Down Expand Up @@ -105,6 +111,9 @@ public override void OnInspectorGUI()
new GUIContent(s_timeScale, s_timeScaleTooltip));
EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(AutopilotSettings.junitReportPath)),
new GUIContent(s_junitReportPath, s_junitReportPathTooltip));
EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(AutopilotSettings.reporter)),
new GUIContent(s_reporter, s_reporterTooltip));
EditorGUILayout.HelpBox(s_obsoletedSlackParamsHelpBox, MessageType.Warning);
EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(AutopilotSettings.slackToken)),
new GUIContent(s_slackToken, s_slackTokenTooltip));
EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(AutopilotSettings.slackChannels)),
Expand Down
15 changes: 11 additions & 4 deletions Runtime/Autopilot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public enum ExitCode
private ILogger _logger;
private RandomFactory _randomFactory;
private IAgentDispatcher _dispatcher;
private IReporter _reporter;
private LogMessageHandler _logMessageHandler;
private AutopilotState _state;
private AutopilotSettings _settings;
Expand All @@ -55,7 +54,7 @@ private void Start()
_settings = _state.settings;
Assert.IsNotNull(_settings);

_logger = new ConsoleLogger(Debug.unityLogger.logHandler);
_logger = CreateLogger();

if (!int.TryParse(_settings.randomSeed, out var seed))
{
Expand All @@ -68,8 +67,7 @@ private void Start()
// NOTE: Registering logMessageReceived must be placed before DispatchByScene.
// Because some agent can throw an error immediately, so reporter can miss the error if
// registering logMessageReceived is placed after DispatchByScene.
_reporter = new SlackReporter(_settings, new SlackAPI());
_logMessageHandler = new LogMessageHandler(_settings, _reporter);
_logMessageHandler = new LogMessageHandler(_settings, _settings.reporter);
Application.logMessageReceivedThreaded += _logMessageHandler.HandleLog;

_dispatcher = new AgentDispatcher(_settings, _logger, _randomFactory);
Expand All @@ -89,6 +87,15 @@ private void Start()
_startTime = Time.realtimeSinceStartup;
}

/// <summary>
/// Returns an agent dispatcher that autopilot uses. You can change a logger by overriding this method
/// </summary>
/// <returns>A new logger</returns>
protected virtual ILogger CreateLogger()
{
return new ConsoleLogger(Debug.unityLogger.logHandler);
}

/// <summary>
/// Terminate when ran specified time.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
// Copyright (c) 2023 DeNA Co., Ltd.
// This software is released under the MIT License.

using System.Threading;
using Cysharp.Threading.Tasks;
using DeNA.Anjin.Settings;
using UnityEngine;

namespace DeNA.Anjin.Reporters
{
/// <summary>
/// Reporter interface
/// Reporter base class
/// </summary>
public interface IReporter
public abstract class AbstractReporter : ScriptableObject
{
/// <summary>
/// Post report log message, stacktrace and screenshot
/// </summary>
/// <param name="settings">Autopilot settings</param>
/// <param name="logString">Log message</param>
/// <param name="stackTrace">Stack trace</param>
/// <param name="type">Log message type</param>
/// <param name="withScreenshot">With screenshot</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns></returns>
UniTask PostReportAsync(string logString, string stackTrace, LogType type, bool withScreenshot);
public abstract UniTask PostReportAsync(
AutopilotSettings settings,
string logString,
string stackTrace,
LogType type,
bool withScreenshot,
CancellationToken cancellationToken = default
);
}
}
File renamed without changes.
44 changes: 44 additions & 0 deletions Runtime/Reporters/CompositeReporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2023 DeNA Co., Ltd.
// This software is released under the MIT License.

using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Cysharp.Threading.Tasks;
using DeNA.Anjin.Settings;
using UnityEngine;

namespace DeNA.Anjin.Reporters
{
/// <summary>
/// A class for reporters that delegate to multiple reporters
/// </summary>
[CreateAssetMenu(fileName = "New CompositeReporter", menuName = "Anjin/Composite Reporter", order = 51)]
public class CompositeReporter : AbstractReporter
{
/// <summary>
/// Reporters to delegate
/// </summary>
public List<AbstractReporter> reporters = new List<AbstractReporter>();


/// <inheritdoc />
public override async UniTask PostReportAsync(
AutopilotSettings settings,
string logString,
string stackTrace,
LogType type,
bool withScreenshot,
CancellationToken cancellationToken = default
)
{
await UniTask.WhenAll(
reporters
.Where(r => r != this && r != null)
.Select(
r => r.PostReportAsync(settings, logString, stackTrace, type, withScreenshot, cancellationToken)
)
);
}
}
}
3 changes: 3 additions & 0 deletions Runtime/Reporters/CompositeReporter.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit be92c72

Please sign in to comment.