Telemetry revisited - Move from App_Data file to UmbracoSettings.config (#9554)

This commit is contained in:
Warren Buckley
2020-12-16 07:50:59 +00:00
committed by GitHub
parent 6a4045c87d
commit 36cb34285c
14 changed files with 148 additions and 402 deletions

2
.gitignore vendored
View File

@@ -176,3 +176,5 @@ cypress.env.json
/src/Umbraco.Tests.AcceptanceTest/cypress/videos/
/src/Umbraco.Tests.AcceptanceTest/cypress/screenshots/
src/Umbraco.Web.UI/Umbraco/telemetrics-id.umb
/src/Umbraco.Web.UI/config/umbracoSettings.config

View File

@@ -8,5 +8,10 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
internal TourConfigElement Tours => (TourConfigElement)this["tours"];
ITourSection IBackOfficeSection.Tours => Tours;
[ConfigurationProperty("id", DefaultValue = "")]
internal string Id => (string)base["id"];
string IBackOfficeSection.Id => (string)base["id"];
}
}

View File

@@ -1,7 +1,10 @@
namespace Umbraco.Core.Configuration.UmbracoSettings
using System;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public interface IBackOfficeSection
{
ITourSection Tours { get; }
string Id { get; }
}
}

View File

@@ -7,7 +7,7 @@ namespace Umbraco.Core.IO
{
public static string TinyMceConfig => SystemDirectories.Config + "/tinyMceConfig.config";
public static string TelemetricsIdentifier => SystemDirectories.Data + "/telemetrics-id.umb";
public static string UmbracoSettings => SystemDirectories.Config + "/UmbracoSettings.config";
// TODO: Kill this off we don't have umbraco.config XML cache we now have NuCache
public static string GetContentCacheXml(IGlobalSettings globalSettings)

View File

@@ -377,6 +377,7 @@
<!-- Create ClientDependency.config file from Template if it doesn't exist -->
<Message Text="Copy ClientDependency.$(Configuration).config to ClientDependency.config" Importance="high" Condition="!Exists('$(ProjectDir)Config\ClientDependency.config')" />
<Copy SourceFiles="$(ProjectDir)Config\ClientDependency.Release.config" DestinationFiles="$(ProjectDir)Config\ClientDependency.config" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="!Exists('$(ProjectDir)Config\ClientDependency.config')" />
<Copy SourceFiles="$(ProjectDir)Config\umbracoSettings.Release.config" DestinationFiles="$(ProjectDir)Config\umbracoSettings.config" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="!Exists('$(ProjectDir)Config\umbracoSettings.config')" />
<!-- Create Serilog.config & serilog.user.config file from Templates if it doesn't exist -->
<Message Text="Copy serilog.$(Configuration).config to serilog.config" Importance="high" Condition="!Exists('$(ProjectDir)Config\serilog.config')" />
<Copy SourceFiles="$(ProjectDir)Config\serilog.Release.config" DestinationFiles="$(ProjectDir)Config\serilog.config" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="!Exists('$(ProjectDir)Config\serilog.config')" />

View File

@@ -41,11 +41,11 @@
<![CDATA[
<div id="umbracoPreviewBadge" class="umbraco-preview-badge">
<span class="umbraco-preview-badge__header">Preview mode</span>
<a href="{0}/preview/?id={2}" class="umbraco-preview-badge__a open">
<a href="{0}/preview/?id={2}" class="umbraco-preview-badge__a open" title="Open preview in BackOffice">
</a>
<a href="{0}/preview/end?redir={1}" class="umbraco-preview-badge__a end">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><title>Click to end</title><path fill="#fff" d="M5273.1 2400.1v-2c0-2.8-5-4-9.7-4s-9.7 1.3-9.7 4v2a7 7 0 002 4.9l5 4.9c.3.3.4.6.4 1v6.4c0 .4.2.7.6.8l2.9.9c.5.1 1-.2 1-.8v-7.2c0-.4.2-.7.4-1l5.1-5a7 7 0 002-4.9zm-9.7-.1c-4.8 0-7.4-1.3-7.5-1.8.1-.5 2.7-1.8 7.5-1.8s7.3 1.3 7.5 1.8c-.2.5-2.7 1.8-7.5 1.8z"/><path fill="#fff" d="M5268.4 2410.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1h-4.3zM5272.7 2413.7h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1zM5272.7 2417h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1 0-.5-.4-1-1-1z"/><path fill="#fff" d="M78.2 13l-8.7 11.7a32.5 32.5 0 11-51.9 25.8c0-10.3 4.7-19.7 12.9-25.8L21.8 13a47 47 0 1056.4 0z"/><path fill="#fff" d="M42.7 2.5h14.6v49.4H42.7z"/></svg>
<a href="{0}/preview/end?redir={1}" class="umbraco-preview-badge__a end" title="End preview mode">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><title>Click to end preview mode</title><path fill="#fff" d="M5273.1 2400.1v-2c0-2.8-5-4-9.7-4s-9.7 1.3-9.7 4v2a7 7 0 002 4.9l5 4.9c.3.3.4.6.4 1v6.4c0 .4.2.7.6.8l2.9.9c.5.1 1-.2 1-.8v-7.2c0-.4.2-.7.4-1l5.1-5a7 7 0 002-4.9zm-9.7-.1c-4.8 0-7.4-1.3-7.5-1.8.1-.5 2.7-1.8 7.5-1.8s7.3 1.3 7.5 1.8c-.2.5-2.7 1.8-7.5 1.8z"/><path fill="#fff" d="M5268.4 2410.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1h-4.3zM5272.7 2413.7h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1zM5272.7 2417h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1 0-.5-.4-1-1-1z"/><path fill="#fff" d="M78.2 13l-8.7 11.7a32.5 32.5 0 11-51.9 25.8c0-10.3 4.7-19.7 12.9-25.8L21.8 13a47 47 0 1056.4 0z"/><path fill="#fff" d="M42.7 2.5h14.6v49.4H42.7z"/></svg>
</a>
</div>
<style type="text/css">
@@ -64,7 +64,7 @@
pointer-events:none;
left: 50%;
transform: translate(-50%, 40px);
animation: umbraco-preview-badge--effect 10s 100ms ease both;
animation: umbraco-preview-badge--effect 10s 1.2s ease both;
border-radius: 3px 3px 0 0;
}}
@keyframes umbraco-preview-badge--effect {{
@@ -91,20 +91,20 @@
3.5%,
6.5%,
8.5% {{
transform: translate(-50%, 0px);
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
9.7% {{
transform: translate(-50%, 0px);
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
10.0% {{
transform: translate(-50%, 0px);
transform: translate(-50%, 0);
}}
60% {{
transform: translate(-50%, 0px);
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
61.5% {{
@@ -126,18 +126,18 @@
63.5%,
66.5%,
68.5% {{
transform: translate(-50%, 0px);
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
69.7% {{
transform: translate(-50%, 0px);
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
70.0% {{
transform: translate(-50%, 0px);
transform: translate(-50%, 0);
}}
100.0% {{
transform: translate(-50%, 0px);
transform: translate(-50%, 0);
}}
}}
.umbraco-preview-badge__header {{
@@ -170,6 +170,7 @@
width:1em;
}}
</style>
<script type="text/javascript" data-umbraco-path="{0}" src="{0}/js/umbraco.websitepreview.js"></script>
]]>
</PreviewBadge>
@@ -231,6 +232,14 @@
By default you can call any content Id in the url and show the content with that id, for example:
http://mysite.com/1092 or http://mysite.com/1092.aspx would render the content with id 1092. Setting
this setting to true stops that behavior
@disableRedirectUrlTracking
When the URL changes for content, redirects are automatically created for redirect handling within the
request pipeline. Setting this setting to true stops the automatic creation of redirects. Note that this
does not stop the request pipeline from handling any previously created redirects.
@urlProviderMode
By default Umbraco automatically figures out if internal URLs should be rendered as relative or absolute,
depending on the current request and the configured domains. By setting this setting to "Relative" or
"Absolute" you can force Umbraco to always render URLs as either relative or absolute.
@umbracoApplicationUrl
The url of the Umbraco application. By default, Umbraco will figure it out from the first request.
Configure it here if you need anything specific. Needs to be a complete url with scheme and umbraco
@@ -242,4 +251,17 @@
umbracoApplicationUrl="">
</web.routing>
<!--
keepAlive
@disableKeepAliveTask
Disables the periodic KeepAliveTask when set to "true".
Use this setting to disable the KeepAliveTask in case you already have an alternative.
For example, Azure App Service has keep alive functionality built-in.
Defaults to "false".
@keepAlivePingUrl
The url of the KeepAlivePing action. By default, the url will use the umbracoApplicationUrl setting as the basis.
Change this setting to specify an alternative url to reach the KeepAlivePing action. eg http://localhost/umbraco/api/keepalive/ping
Defaults to "{umbracoApplicationUrl}/api/keepalive/ping".
-->
<keepAlive disableKeepAliveTask="false" keepAlivePingUrl="{umbracoApplicationUrl}/api/keepalive/ping" />
</settings>

View File

@@ -1,267 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<settings>
<!--
umbracoSettings.config configuration documentation can be found here:
https://our.umbraco.com/documentation/using-umbraco/config-files/umbracoSettings/
Many of the optional settings are not explicitly listed here
but can be found in the online documentation.
-->
<backOffice>
<tours enable="true"></tours>
</backOffice>
<content>
<errors>
<error404>1</error404>
<!--
The value for error pages can be:
* A content item's GUID ID (example: 26C1D84F-C900-4D53-B167-E25CC489DAC8)
* An XPath statement (example: //errorPages[@nodeName='My cool error']
* A content item's integer ID (example: 1234)
-->
<!--
<error404>
<errorPage culture="default">26C1D84F-C900-4D53-B167-E25CC489DAC8</errorPage>
<errorPage culture="en-US">D820E120-6865-4D88-BFFE-48801A6AC375</errorPage>
</error404>
-->
</errors>
<notifications>
<!-- the email that should be used as from mail when umbraco sends a notification -->
<!-- you can add a display name to the email like this: <email>Your display name here &lt;your@email.here&gt;</email> -->
<email>your@email.here</email>
</notifications>
<!-- The html injected into a (x)html page if Umbraco is running in preview mode -->
<PreviewBadge>
<![CDATA[
<div id="umbracoPreviewBadge" class="umbraco-preview-badge">
<span class="umbraco-preview-badge__header">Preview mode</span>
<a href="{0}/preview/?id={2}" class="umbraco-preview-badge__a open" title="Open preview in BackOffice">
</a>
<a href="{0}/preview/end?redir={1}" class="umbraco-preview-badge__a end" title="End preview mode">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><title>Click to end preview mode</title><path fill="#fff" d="M5273.1 2400.1v-2c0-2.8-5-4-9.7-4s-9.7 1.3-9.7 4v2a7 7 0 002 4.9l5 4.9c.3.3.4.6.4 1v6.4c0 .4.2.7.6.8l2.9.9c.5.1 1-.2 1-.8v-7.2c0-.4.2-.7.4-1l5.1-5a7 7 0 002-4.9zm-9.7-.1c-4.8 0-7.4-1.3-7.5-1.8.1-.5 2.7-1.8 7.5-1.8s7.3 1.3 7.5 1.8c-.2.5-2.7 1.8-7.5 1.8z"/><path fill="#fff" d="M5268.4 2410.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1h-4.3zM5272.7 2413.7h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1s-.4-1-1-1zM5272.7 2417h-4.3c-.6 0-1 .4-1 1s.4 1 1 1h4.3c.6 0 1-.4 1-1 0-.5-.4-1-1-1z"/><path fill="#fff" d="M78.2 13l-8.7 11.7a32.5 32.5 0 11-51.9 25.8c0-10.3 4.7-19.7 12.9-25.8L21.8 13a47 47 0 1056.4 0z"/><path fill="#fff" d="M42.7 2.5h14.6v49.4H42.7z"/></svg>
</a>
</div>
<style type="text/css">
.umbraco-preview-badge {{
position: fixed;
bottom: 0;
display: inline-flex;
background: rgba(27, 38, 79, 0.9);
color: #fff;
font-size: 12px;
z-index: 99999999;
justify-content: center;
align-items: center;
box-shadow: 0 5px 10px rgba(0, 0, 0, .2), 0 1px 2px rgba(0, 0, 0, .2);
line-height: 1;
pointer-events:none;
left: 50%;
transform: translate(-50%, 40px);
animation: umbraco-preview-badge--effect 10s 1.2s ease both;
border-radius: 3px 3px 0 0;
}}
@keyframes umbraco-preview-badge--effect {{
0% {{
transform: translate(-50%, 40px);
animation-timing-function: ease-out;
}}
1.5% {{
transform: translate(-50%, -20px);
animation-timing-function: ease-in;
}}
5.0% {{
transform: translate(-50%, -8px);
animation-timing-function: ease-in;
}}
7.5% {{
transform: translate(-50%, -4px);
animation-timing-function: ease-in;
}}
9.2% {{
transform: translate(-50%, -2px);
animation-timing-function: ease-in;
}}
3.5%,
6.5%,
8.5% {{
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
9.7% {{
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
10.0% {{
transform: translate(-50%, 0);
}}
60% {{
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
61.5% {{
transform: translate(-50%, -20px);
animation-timing-function: ease-in;
}}
65.0% {{
transform: translate(-50%, -8px);
animation-timing-function: ease-in;
}}
67.5% {{
transform: translate(-50%, -4px);
animation-timing-function: ease-in;
}}
69.2% {{
transform: translate(-50%, -2px);
animation-timing-function: ease-in;
}}
63.5%,
66.5%,
68.5% {{
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
69.7% {{
transform: translate(-50%, 0);
animation-timing-function: ease-out;
}}
70.0% {{
transform: translate(-50%, 0);
}}
100.0% {{
transform: translate(-50%, 0);
}}
}}
.umbraco-preview-badge__header {{
padding: 1em;
font-weight: bold;
pointer-events:none;
}}
.umbraco-preview-badge__a {{
width: 3em;
padding: 1em;
display: flex;
flex-shrink: 0;
align-items: center;
align-self: stretch;
color:white;
text-decoration:none;
font-weight: bold;
border-left: 1px solid hsla(0,0%,100%,.25);
pointer-events:all;
}}
.umbraco-preview-badge__a svg {{
width: 1em;
height:1em;
}}
.umbraco-preview-badge__a:hover {{
background: #202d5e;
}}
.umbraco-preview-badge__end svg {{
fill: #fff;
width:1em;
}}
</style>
<script type="text/javascript" data-umbraco-path="{0}" src="{0}/js/umbraco.websitepreview.js"></script>
]]>
</PreviewBadge>
<!-- How Umbraco should handle errors during macro execution. Can be one of the following values:
- inline - show an inline error within the macro but allow the page to continue rendering. Historial Umbraco behaviour.
- silent - Silently suppress the error and do not render the offending macro.
- throw - Throw an exception which can be caught by the global error handler defined in Application_OnError. If no such
error handler is defined then you'll see the Yellow Screen Of Death (YSOD) error page.
Note the error can also be handled by the umbraco.macro.Error event, where you can log/alarm with your own code and change the behaviour per event. -->
<MacroErrors>throw</MacroErrors>
<!-- These file types will not be allowed to be uploaded via the upload control for media and content -->
<disallowedUploadFiles>ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,swf,xml,xhtml,html,htm,php,htaccess</disallowedUploadFiles>
<!-- You can specify your own background image for the login screen here. This path is relative to the ~/umbraco path. The default location is: /umbraco/assets/img/login.jpg -->
<loginBackgroundImage>assets/img/login.jpg</loginBackgroundImage>
</content>
<security>
<!-- set to true to auto update login interval (and there by disabling the lock screen -->
<keepUserLoggedIn>false</keepUserLoggedIn>
<!-- by default this is true and if not specified in config will be true. set to false to always show a separate username field in the back office user editor -->
<usernameIsEmail>true</usernameIsEmail>
<!-- change in 4.8: Disabled users are now showed dimmed and last in the tree. If you prefer not to display them set this to true -->
<hideDisabledUsersInBackoffice>false</hideDisabledUsersInBackoffice>
</security>
<requestHandler>
<!-- this ensures that all url segments are turned to ASCII as much as we can -->
<urlReplacing toAscii="try" />
</requestHandler>
<!--
web.routing
@trySkipIisCustomErrors
Tries to skip IIS custom errors.
Starting with IIS 7.5, this must be set to true for Umbraco 404 pages to show. Else, IIS will take
over and render its built-in error page. See MS doc for HttpResponseBase.TrySkipIisCustomErrors.
The default value is false, for backward compatibility reasons, which means that IIS _will_ take
over, and _prevent_ Umbraco 404 pages to show.
@internalRedirectPreservesTemplate
By default as soon as we're not displaying the initial document, we reset the template set by the
finder or by the alt. template. Set this option to true to preserve the template set by the finder
or by the alt. template, in case of an internal redirect.
(false by default, and in fact should remain false unless you know what you're doing)
@disableAlternativeTemplates
By default you can add a altTemplate querystring or append a template name to the current URL which
will make Umbraco render the content on the current page with the template you requested, for example:
http://mysite.com/about-us/?altTemplate=Home and http://mysite.com/about-us/Home would render the
"About Us" page with a template with the alias Home. Setting this setting to true stops that behavior
@validateAlternativeTemplates
By default you can add a altTemplate querystring or append a template name to the current URL which
will make Umbraco render the content on the current page with the template you requested, for example:
http://mysite.com/about-us/?altTemplate=Home and http://mysite.com/about-us/Home would render the
"About Us" page with a template with the alias Home. Setting this setting to true will ensure that
only templates that have been permitted on the document type will be allowed
@disableFindContentByIdPath
By default you can call any content Id in the url and show the content with that id, for example:
http://mysite.com/1092 or http://mysite.com/1092.aspx would render the content with id 1092. Setting
this setting to true stops that behavior
@disableRedirectUrlTracking
When the URL changes for content, redirects are automatically created for redirect handling within the
request pipeline. Setting this setting to true stops the automatic creation of redirects. Note that this
does not stop the request pipeline from handling any previously created redirects.
@urlProviderMode
By default Umbraco automatically figures out if internal URLs should be rendered as relative or absolute,
depending on the current request and the configured domains. By setting this setting to "Relative" or
"Absolute" you can force Umbraco to always render URLs as either relative or absolute.
@umbracoApplicationUrl
The url of the Umbraco application. By default, Umbraco will figure it out from the first request.
Configure it here if you need anything specific. Needs to be a complete url with scheme and umbraco
path, eg http://mysite.com/umbraco. NOT just "mysite.com" or "mysite.com/umbraco" or "http://mysite.com".
-->
<web.routing
trySkipIisCustomErrors="true"
internalRedirectPreservesTemplate="false" disableAlternativeTemplates="false" validateAlternativeTemplates="false" disableFindContentByIdPath="false"
umbracoApplicationUrl="">
</web.routing>
<!--
keepAlive
@disableKeepAliveTask
Disables the periodic KeepAliveTask when set to "true".
Use this setting to disable the KeepAliveTask in case you already have an alternative.
For example, Azure App Service has keep alive functionality built-in.
Defaults to "false".
@keepAlivePingUrl
The url of the KeepAlivePing action. By default, the url will use the umbracoApplicationUrl setting as the basis.
Change this setting to specify an alternative url to reach the KeepAlivePing action. eg http://localhost/umbraco/api/keepalive/ping
Defaults to "{umbracoApplicationUrl}/api/keepalive/ping".
-->
<keepAlive disableKeepAliveTask="false" keepAlivePingUrl="{umbracoApplicationUrl}/api/keepalive/ping" />
</settings>

View File

@@ -21,6 +21,7 @@ namespace Umbraco.Web.Install
a.OfType<NewInstallStep>().First(),
a.OfType<UpgradeStep>().First(),
a.OfType<FilePermissionsStep>().First(),
a.OfType<TelemetryIdentifierStep>().First(),
a.OfType<ConfigureMachineKey>().First(),
a.OfType<DatabaseConfigureStep>().First(),
a.OfType<DatabaseInstallStep>().First(),

View File

@@ -0,0 +1,78 @@
using System;
using System.IO;
using System.Threading.Tasks;
using System.Xml.Linq;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Web.Install.Models;
namespace Umbraco.Web.Install.InstallSteps
{
[InstallSetupStep(InstallationType.NewInstall | InstallationType.Upgrade,
"TelemetryIdConfiguration", 0, "",
PerformsAppRestart = false)]
internal class TelemetryIdentifierStep : InstallSetupStep<object>
{
private readonly IProfilingLogger _logger;
private readonly IUmbracoSettingsSection _settings;
public TelemetryIdentifierStep(IProfilingLogger logger, IUmbracoSettingsSection settings)
{
_logger = logger;
_settings = settings;
}
public override Task<InstallSetupResult> ExecuteAsync(object model)
{
// Generate GUID
var telemetrySiteIdentifier = Guid.NewGuid();
// Modify the XML to add a new GUID site identifier
// hack: ensure this does not trigger a restart
using (ChangesMonitor.Suspended())
{
var umbracoSettingsPath = IOHelper.MapPath(SystemFiles.UmbracoSettings);
if(File.Exists(umbracoSettingsPath) == false)
{
// Log an error
_logger.Error<TelemetryIdentifierStep>("Unable to find umbracoSettings.config file to add telemetry site identifier");
return Task.FromResult<InstallSetupResult>(null);
}
try
{
var umbracoConfigXml = XDocument.Load(umbracoSettingsPath, LoadOptions.PreserveWhitespace);
if (umbracoConfigXml.Root != null)
{
var backofficeElement = umbracoConfigXml.Root.Element("backOffice");
if (backofficeElement == null)
return Task.FromResult<InstallSetupResult>(null);
// Will add ID attribute if it does not exist
backofficeElement.SetAttributeValue("id", telemetrySiteIdentifier.ToString());
// Save file back down
umbracoConfigXml.Save(umbracoSettingsPath, SaveOptions.DisableFormatting);
}
}
catch (Exception ex)
{
_logger.Error<TelemetryIdentifierStep>(ex, "Couldn't update umbracoSettings.config with a backoffice with a telemetry site identifier");
}
}
return Task.FromResult<InstallSetupResult>(null);
}
public override bool RequiresExecution(object model)
{
// Verify that XML attribute is not empty string
// Try & get a value stored in umbracoSettings.config on the backoffice XML element ID attribute
var backofficeIdentifierRaw = _settings.BackOffice.Id;
// No need to add Id again if already found
return string.IsNullOrEmpty(backofficeIdentifierRaw);
}
}
}

View File

@@ -1,6 +1,5 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Text;
@@ -8,7 +7,7 @@ using System.Threading;
using System.Threading.Tasks;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Web.Scheduling;
@@ -16,62 +15,33 @@ namespace Umbraco.Web.Telemetry
{
public class ReportSiteTask : RecurringTaskBase
{
private IProfilingLogger _logger;
private readonly IProfilingLogger _logger;
private static HttpClient _httpClient;
private readonly IUmbracoSettingsSection _settings;
public ReportSiteTask(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayBeforeWeStart, int howOftenWeRepeat, IProfilingLogger logger)
public ReportSiteTask(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayBeforeWeStart, int howOftenWeRepeat, IProfilingLogger logger, IUmbracoSettingsSection settings)
: base(runner, delayBeforeWeStart, howOftenWeRepeat)
{
_logger = logger;
_httpClient = new HttpClient();
_settings = settings;
}
/// <summary>
/// Runs the background task to send the anynomous ID
/// Runs the background task to send the anonymous ID
/// to telemetry service
/// </summary>
/// <returns>A value indicating whether to repeat the task.</returns>
public override async Task<bool> PerformRunAsync(CancellationToken token)
{
// Try & find file at '/umbraco/telemetrics-id.umb'
var telemetricsFilePath = IOHelper.MapPath(SystemFiles.TelemetricsIdentifier);
if (File.Exists(telemetricsFilePath) == false)
{
// Some users may have decided to not be tracked by deleting/removing the marker file
_logger.Warn<ReportSiteTask>("No telemetry marker file found at '{filePath}' and will not report site to telemetry service", telemetricsFilePath);
// Stop repeating this task (no need to keep checking)
// The only time it will recheck when the site is recycled
return false;
}
var telemetricsFileContents = string.Empty;
try
{
// Open file & read its contents
// It may throw due to file permissions or file locking
telemetricsFileContents = File.ReadAllText(telemetricsFilePath);
}
catch (Exception ex)
{
// Silently swallow ex - but lets log it (ReadAllText throws a ton of different types of ex)
// Hence the use of general exception type
_logger.Error<ReportSiteTask>(ex, "Error in reading file contents of telemetry marker file found at '{filePath}'", telemetricsFilePath);
// Exit out early, but mark this task to be repeated in case its a file lock so it can be rechecked the next time round
return true;
}
// Try & get a value stored in umbracoSettings.config on the backoffice XML element ID attribute
var backofficeIdentifierRaw = _settings.BackOffice.Id;
// Parse as a GUID & verify its a GUID and not some random string
// In case of users may have messed or decided to empty the file contents or put in something random
if (Guid.TryParse(telemetricsFileContents, out var telemetrySiteIdentifier) == false)
if (Guid.TryParse(backofficeIdentifierRaw, out var telemetrySiteIdentifier) == false)
{
// Some users may have decided to mess with file contents
_logger.Warn<ReportSiteTask>("The telemetry marker file found at '{filePath}' with '{telemetrySiteId}' is not a valid identifier for the telemetry service", telemetricsFilePath, telemetrySiteIdentifier);
// Some users may have decided to mess with the XML attribute and put in something else
// Stop repeating this task (no need to keep checking)
// The only time it will recheck when the site is recycled
return false;
@@ -79,7 +49,6 @@ namespace Umbraco.Web.Telemetry
try
{
// Send data to LIVE telemetry
_httpClient.BaseAddress = new Uri("https://telemetry.umbraco.com/");
@@ -101,14 +70,14 @@ namespace Umbraco.Web.Telemetry
// Make a HTTP Post to telemetry service
// https://telemetry.umbraco.com/installs/
// Fire & Forget, do not need to know if its a 200, 500 etc
var result = await _httpClient.SendAsync(request);
var result = await _httpClient.SendAsync(request, token);
}
}
catch
{
// Silently swallow
// The user does not need the logs being polluted if our service has fallen over or is down etc
// Hence only loggigng this at a more verbose level (Which users should not be using in prod)
// Hence only logging this at a more verbose level (which users should not be using in production)
_logger.Debug<ReportSiteTask>("There was a problem sending a request to the Umbraco telemetry service");
}
@@ -118,7 +87,6 @@ namespace Umbraco.Web.Telemetry
public override bool IsAsync => true;
[DataContract]
private class TelemetryReportData
{

View File

@@ -1,4 +1,5 @@
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Web.Scheduling;
@@ -6,12 +7,14 @@ namespace Umbraco.Web.Telemetry
{
public class TelemetryComponent : IComponent
{
private IProfilingLogger _logger;
private readonly IProfilingLogger _logger;
private readonly IUmbracoSettingsSection _settings;
private BackgroundTaskRunner<IBackgroundTask> _telemetryReporterRunner;
public TelemetryComponent(IProfilingLogger logger)
public TelemetryComponent(IProfilingLogger logger, IUmbracoSettingsSection settings)
{
_logger = logger;
_settings = settings;
}
public void Initialize()
@@ -19,11 +22,11 @@ namespace Umbraco.Web.Telemetry
// backgrounds runners are web aware, if the app domain dies, these tasks will wind down correctly
_telemetryReporterRunner = new BackgroundTaskRunner<IBackgroundTask>("TelemetryReporter", _logger);
int delayBeforeWeStart = 60 * 1000; // 60 * 1000ms = 1min (60,000)
int howOftenWeRepeat = 60 * 1000 * 60 * 24; // 60 * 1000 * 60 * 24 = 24hrs (86400000)
const int delayBeforeWeStart = 60 * 1000; // 60 * 1000ms = 1min (60,000)
const int howOftenWeRepeat = 60 * 1000 * 60 * 24; // 60 * 1000 * 60 * 24 = 24hrs (86400000)
// As soon as we add our task to the runner it will start to run (after its delay period)
var task = new ReportSiteTask(_telemetryReporterRunner, delayBeforeWeStart, howOftenWeRepeat, _logger);
var task = new ReportSiteTask(_telemetryReporterRunner, delayBeforeWeStart, howOftenWeRepeat, _logger, _settings);
_telemetryReporterRunner.TryAdd(task);
}

View File

@@ -1,60 +0,0 @@
using System;
using System.IO;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Telemetry
{
public class TelemetryMarkerComponent : IComponent
{
private IProfilingLogger _logger;
private IRuntimeState _runtime;
public TelemetryMarkerComponent(IProfilingLogger logger, IRuntimeState runtime)
{
_logger = logger;
_runtime = runtime;
}
public void Initialize()
{
var telemetricsFilePath = IOHelper.MapPath(SystemFiles.TelemetricsIdentifier);
// Verify file does not exist already (if we are upgrading)
// In a clean install we know it would not exist
// If the site is upgraded and the file was removed it would re-create one
// NOTE: If user removed the marker file to opt out it would re-create a new guid marker file & potentially skew
if (_runtime.Level == RuntimeLevel.Upgrade && File.Exists(telemetricsFilePath))
{
_logger.Warn<TelemetryMarkerComponent>("When upgrading the anonymous telemetry file already existsed on disk at {filePath}", telemetricsFilePath);
return;
}
else if (_runtime.Level == RuntimeLevel.Install && File.Exists(telemetricsFilePath))
{
// No need to log for when level is install if file exists (As this component hit several times during install process)
return;
}
// We are a clean install or an upgrade without the marker file
// Generate GUID
var telemetrySiteIdentifier = Guid.NewGuid();
// Write file contents
try
{
File.WriteAllText(telemetricsFilePath, telemetrySiteIdentifier.ToString());
}
catch (Exception ex)
{
_logger.Error<TelemetryMarkerComponent>(ex, "Unable to create telemetry file at {filePath}", telemetricsFilePath);
}
}
public void Terminate()
{
}
}
}

View File

@@ -1,9 +0,0 @@
using Umbraco.Core;
using Umbraco.Core.Composing;
namespace Umbraco.Web.Telemetry
{
[RuntimeLevel(MinLevel = RuntimeLevel.Install, MaxLevel = RuntimeLevel.Upgrade)]
public class TelemetryMarkerComposer : ComponentComposer<TelemetryMarkerComponent>, ICoreComposer
{ }
}

View File

@@ -173,6 +173,7 @@
<Compile Include="Editors\TinyMceController.cs" />
<Compile Include="HealthCheck\Checks\Data\DatabaseIntegrityCheck.cs" />
<Compile Include="ImageCropperTemplateCoreExtensions.cs" />
<Compile Include="Install\InstallSteps\TelemetryIdentifierStep.cs" />
<Compile Include="IUmbracoContextFactory.cs" />
<Compile Include="Install\ChangesMonitor.cs" />
<Compile Include="Logging\WebProfiler.cs" />
@@ -296,10 +297,8 @@
<Compile Include="Models\LinkType.cs" />
<Compile Include="Models\TemplateQuery\OperatorFactory.cs" />
<Compile Include="Telemetry\ReportSiteTask.cs" />
<Compile Include="Telemetry\TelemetryMarkerComponent.cs" />
<Compile Include="Telemetry\TelemetryComponent.cs" />
<Compile Include="Telemetry\TelemetryComposer.cs" />
<Compile Include="Telemetry\TelemetryMarkerComposer.cs" />
<Compile Include="Templates\HtmlLocalLinkParser.cs" />
<Compile Include="Templates\HtmlImageSourceParser.cs" />
<Compile Include="Templates\HtmlUrlParser.cs" />