Skip to content

Commit

Permalink
Add telemetry for Svg preview handler (#1314)
Browse files Browse the repository at this point in the history
* Added telemetry events for Svg Preview Handler

* Added unit test in case preview handler throws

* Updated the Error event name

* Remove the not required return statement
  • Loading branch information
udit3333 authored Feb 19, 2020
1 parent c566392 commit ef548ed
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 18 deletions.

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

3 changes: 3 additions & 0 deletions src/modules/previewpane/SvgPreviewHandler/Resource.resx
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,7 @@
<data name="BlockedElementInfoText" xml:space="preserve">
<value>Some elements have been blocked to help prevent the sender from identifying your computer. Open this item to view all elements.</value>
</data>
<data name="SvgNotPreviewedError" xml:space="preserve">
<value>The Svg could not be preview due to an internal error in Svg Preview Handler.</value>
</data>
</root>
50 changes: 32 additions & 18 deletions src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.Versioning;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
Expand All @@ -33,9 +34,9 @@ public class SvgPreviewControl : FormHandlerControl
private RichTextBox textBox;

/// <summary>
/// Represent if any blocked element is found in the Svg.
/// Represent if an text box info bar is added for showing message.
/// </summary>
private bool foundFilteredElements = false;
private bool infoBarAdded = false;

/// <summary>
/// Start the preview on the Control.
Expand All @@ -45,25 +46,37 @@ public override void DoPreview<T>(T dataSource)
{
this.InvokeOnControlThread(() =>
{
this.foundFilteredElements = false;
string svgData = null;
using (var stream = new StreamWrapper(dataSource as IStream))
try
{
using (var reader = new StreamReader(stream))
this.infoBarAdded = false;
string svgData = null;
using (var stream = new StreamWrapper(dataSource as IStream))
{
svgData = reader.ReadToEnd();
using (var reader = new StreamReader(stream))
{
svgData = reader.ReadToEnd();
}
}
svgData = string.IsNullOrWhiteSpace(svgData) ? svgData : SvgPreviewHandlerHelper.RemoveElements(svgData, out this.infoBarAdded);
if (this.infoBarAdded)
{
this.AddTextBoxControl(Resource.BlockedElementInfoText);
}
}
svgData = string.IsNullOrWhiteSpace(svgData) ? svgData : SvgPreviewHandlerHelper.RemoveElements(svgData, out this.foundFilteredElements);
if (this.foundFilteredElements)
this.AddBrowserControl(svgData);
this.Resize += this.FormResized;
base.DoPreview(dataSource);
SvgTelemetry.Log.SvgFilePreviewed();
}
catch (Exception ex)
{
this.AddTextBoxControl();
SvgTelemetry.Log.SvgFilePreviewError(ex.Message);
this.Controls.Clear();
this.infoBarAdded = true;
this.AddTextBoxControl(Resource.SvgNotPreviewedError);
base.DoPreview(dataSource);
}
this.AddBrowserControl(svgData);
this.Resize += this.FormResized;
base.DoPreview(dataSource);
});
}

Expand All @@ -85,7 +98,7 @@ private void RTBContentsResized(object sender, ContentsResizedEventArgs e)
/// <param name="e">Provides data for the resize event.</param>
private void FormResized(object sender, EventArgs e)
{
if (this.foundFilteredElements)
if (this.infoBarAdded)
{
this.textBox.Width = this.Width;
}
Expand All @@ -109,10 +122,11 @@ private void AddBrowserControl(string svgData)
/// <summary>
/// Adds a Text Box in Controls for showing information about blocked elements.
/// </summary>
private void AddTextBoxControl()
/// <param name="message">Message to be displayed in textbox.</param>
private void AddTextBoxControl(string message)
{
this.textBox = new RichTextBox();
this.textBox.Text = Resource.BlockedElementInfoText;
this.textBox.Text = message;
this.textBox.BackColor = Color.LightYellow;
this.textBox.Multiline = true;
this.textBox.Dock = DockStyle.Top;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
</Compile>
<Compile Include="SvgPreviewHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SvgTelemetry.cs" />
<Compile Include="Utilities\SvgPreviewHandlerHelper.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
70 changes: 70 additions & 0 deletions src/modules/previewpane/SvgPreviewHandler/SvgTelemetry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics.Tracing;
using PreviewHandlerCommon.Telemetry;

namespace SvgPreviewHandler
{
/// <summary>
/// Telemetry helper class for Svg renderer.
/// </summary>
public class SvgTelemetry : TelemetryBase
{
/// <summary>
/// Name for ETW event.
/// </summary>
private const string EventSourceName = "Microsoft.PowerToys";

/// <summary>
/// ETW event name when Svg is previewed.
/// </summary>
private const string SvgFilePreviewedEventName = "PowerPreview_SVGRenderer_Previewed";

/// <summary>
/// ETW event name when error is thrown during Svg preview.
/// </summary>
private const string SvgFilePreviewErrorEventName = "PowerPreview_SVGRenderer_Error";

/// <summary>
/// Initializes a new instance of the <see cref="SvgTelemetry"/> class.
/// </summary>
public SvgTelemetry()
: base(EventSourceName)
{
}

/// <summary>
/// Gets an instance of the <see cref="SvgTelemetry"/> class.
/// </summary>
public static SvgTelemetry Log { get; } = new SvgTelemetry();

/// <summary>
/// Publishes ETW event when svg is previewed successfully.
/// </summary>
public void SvgFilePreviewed()
{
this.Write(SvgFilePreviewedEventName, new EventSourceOptions()
{
Keywords = ProjectKeywordMeasure,
Tags = ProjectTelemetryTagProductAndServicePerformance,
});
}

/// <summary>
/// Publishes ETW event when svg could not be previewed.
/// </summary>
public void SvgFilePreviewError(string message)
{
this.Write(
SvgFilePreviewErrorEventName,
new EventSourceOptions()
{
Keywords = ProjectKeywordMeasure,
Tags = ProjectTelemetryTagProductAndServicePerformance,
},
new { Message = message, });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,31 @@ public void SvgPreviewControl_RichTextBoxWidthShouldAdjust_IfParentControlWidthC
Assert.AreEqual(finalParentWidth, textBox.Width);
}

[TestMethod]
public void SvgPreviewControl_ShouldAddValidTextBox_IfSvgPreviewThrows()
{
// Arrange
var svgPreviewControl = new SvgPreviewControl();
var mockStream = new Mock<IStream>();
mockStream
.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<IntPtr>()))
.Throws(new Exception());

// Act
svgPreviewControl.DoPreview(mockStream.Object);
var textBox = svgPreviewControl.Controls[0] as RichTextBox;

// Assert
Assert.IsFalse(string.IsNullOrWhiteSpace(textBox.Text));
Assert.AreEqual(svgPreviewControl.Controls.Count, 1);
Assert.AreEqual(textBox.Dock, DockStyle.Top);
Assert.AreEqual(textBox.BackColor, Color.LightYellow);
Assert.IsTrue(textBox.Multiline);
Assert.IsTrue(textBox.ReadOnly);
Assert.AreEqual(textBox.ScrollBars, RichTextBoxScrollBars.None);
Assert.AreEqual(textBox.BorderStyle, BorderStyle.None);
}

private IStream GetMockStream(string streamData)
{
var mockStream = new Mock<IStream>();
Expand Down

0 comments on commit ef548ed

Please sign in to comment.