Skip to content

Commit

Permalink
Introduce annotations on Agent types (#990)
Browse files Browse the repository at this point in the history
This commit introduces annotations to agent types
that detail the APM server spec constraints.

- Rename to TruncateJsonConverter
- Use MaxLengthAttribute to specify maxLength constraint
- Rename SanitizationAttribute to SanitizeAttribute
- Move Truncate to StringExtensions
- Add RequiredAttribute
- Move SpanCount into Api namespace and add
as a property on ITransaction.
  • Loading branch information
russcam authored Oct 26, 2020
1 parent 21f481a commit a4b5c33
Show file tree
Hide file tree
Showing 31 changed files with 242 additions and 152 deletions.
6 changes: 3 additions & 3 deletions src/Elastic.Apm/Api/CapturedException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
// See the LICENSE file in the project root for more information

using System.Collections.Generic;
using Elastic.Apm.Api.Constraints;
using Elastic.Apm.Helpers;
using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;

namespace Elastic.Apm.Api
{
public class CapturedException
{
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Code { get; set; }

public bool Handled { get; set; }
Expand All @@ -21,7 +21,7 @@ public class CapturedException
[JsonProperty("stacktrace")]
public List<CapturedStackFrame> StackTrace { get; set; }

[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Type { get; set; }

public override string ToString() => new ToStringBuilder(nameof(CapturedException))
Expand Down
34 changes: 34 additions & 0 deletions src/Elastic.Apm/Api/Constraints/MaxLengthAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to Elasticsearch B.V under
// one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;

namespace Elastic.Apm.Api.Constraints
{
/// <summary>
/// Specifies the maximum length of string data allowed in a property, based on the APM server specification.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public sealed class MaxLengthAttribute : Attribute
{
/// <summary>
/// The maximum length.
/// </summary>
public int Length { get; }

/// <summary>
/// Initializes a new instance of <see cref="MaxLengthAttribute"/>
/// with a maximum length of <see cref="Consts.PropertyMaxLength"/>
/// </summary>
public MaxLengthAttribute() : this(Consts.PropertyMaxLength)
{
}

/// <summary>
/// Initializes a new instance of <see cref="MaxLengthAttribute"/> with a given maximum length
/// </summary>
public MaxLengthAttribute(int length) => Length = length;
}
}
15 changes: 15 additions & 0 deletions src/Elastic.Apm/Api/Constraints/RequiredAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to Elasticsearch B.V under
// one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;

namespace Elastic.Apm.Api.Constraints
{
/// <summary>
/// Specifies that a data field value is required.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public sealed class RequiredAttribute : Attribute { }
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;

namespace Elastic.Apm.Report.Serialization
{
/// <summary>
/// An attribute to mark fields for sanitization. This attribute is known to <see cref="ElasticApmContractResolver"/> and it applies a Converter
/// to sanitize field(s) accordingly.
/// </summary>
internal class SanitizationAttribute : Attribute { }
}
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;
using Elastic.Apm.Report.Serialization;

namespace Elastic.Apm.Api.Constraints
{
/// <summary>
/// An attribute to mark fields for sanitization. This attribute is known to <see cref="ElasticApmContractResolver"/> and it applies a Converter
/// to sanitize field(s) accordingly.
/// </summary>
internal sealed class SanitizeAttribute : Attribute { }
}
6 changes: 3 additions & 3 deletions src/Elastic.Apm/Api/Container.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;
using Elastic.Apm.Api.Constraints;

namespace Elastic.Apm.Api
{
public class Container
{
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[Required]
[MaxLength]
public string Id { get; set; }
}
}
5 changes: 2 additions & 3 deletions src/Elastic.Apm/Api/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;
using Elastic.Apm.Api.Constraints;

namespace Elastic.Apm.Api
{
Expand All @@ -18,7 +17,7 @@ public class Database

public string Instance { get; set; }

[JsonConverter(typeof(TrimmedStringJsonConverter), 10_000)]
[MaxLength(10_000)]
public string Statement { get; set; }

public string Type { get; set; }
Expand Down
11 changes: 5 additions & 6 deletions src/Elastic.Apm/Api/Destination.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;
using Elastic.Apm.Api.Constraints;

namespace Elastic.Apm.Api
{
Expand All @@ -24,7 +23,7 @@ public class Destination
/// (for example <see cref="SpanContext.Http" /> or <see cref="SpanContext.Db" />).
/// Explicitly setting this property to <c>null</c> will prohibit this automatic deduction.
/// </summary>
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Address
{
get => _address.Value;
Expand Down Expand Up @@ -72,20 +71,20 @@ public class DestinationService
/// <summary>
/// Identifier for the destination service (e.g. 'http://elastic.co', 'elasticsearch', 'rabbitmq')"
/// </summary>
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Name { get; set; }

/// <summary>
/// Identifier for the destination service resource being operated on (e.g. 'http://elastic.co:80', 'elasticsearch',
/// 'rabbitmq/queue_name')
/// </summary>
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Resource { get; set; }

/// <summary>
/// Type of the destination service (e.g. 'db', 'elasticsearch'). Should typically be the same as span.type.
/// </summary>
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Type { get; set; }
}

Expand Down
3 changes: 2 additions & 1 deletion src/Elastic.Apm/Api/Http.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System;
using System.Net.Http;
using Elastic.Apm.Api.Constraints;
using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;

Expand All @@ -18,7 +19,7 @@ public class Http
private Uri _originalUrl;
private string _url;

[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Method { get; set; }

/// <summary>
Expand Down
4 changes: 4 additions & 0 deletions src/Elastic.Apm/Api/IExecutionSegment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Elastic.Apm.Api.Constraints;

namespace Elastic.Apm.Api
{
Expand All @@ -21,11 +22,13 @@ public interface IExecutionSegment
/// is automatically calculated when <see cref="End" /> is called.
/// </summary>
/// <value>The duration.</value>
[Required]
double? Duration { get; set; }

/// <summary>
/// The id of the item.
/// </summary>
[Required]
string Id { get; }

/// <summary>
Expand Down Expand Up @@ -65,6 +68,7 @@ public interface IExecutionSegment
/// <summary>
/// Hex encoded 128 random bits ID of the correlated trace.
/// </summary>
[Required]
string TraceId { get; }

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/Elastic.Apm/Api/IMetricSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information

using System.Collections.Generic;
using Elastic.Apm.Api.Constraints;

namespace Elastic.Apm.Api
{
Expand All @@ -14,6 +15,7 @@ public interface IMetricSet
/// <summary>
/// List of captured metrics as key - value pairs
/// </summary>
[Required]
IEnumerable<MetricSample> Samples { get; set; }

// TODO: Rename to Timestamp for consistency?
Expand Down
9 changes: 9 additions & 0 deletions src/Elastic.Apm/Api/ITransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// See the LICENSE file in the project root for more information

using System.Collections.Generic;
using Elastic.Apm.Api.Constraints;
using Elastic.Apm.Model;

namespace Elastic.Apm.Api
{
Expand Down Expand Up @@ -35,8 +37,15 @@ public interface ITransaction : IExecutionSegment
/// The type of the transaction.
/// Example: 'request'
/// </summary>
[Required]
string Type { get; set; }

/// <summary>
/// The total number of correlated spans, including started and dropped
/// </summary>
[Required]
SpanCount SpanCount { get; }

/// <summary>
/// If the transaction does not have a ParentId yet, calling this method generates a new ID, sets it as the ParentId of
/// this transaction,
Expand Down
5 changes: 2 additions & 3 deletions src/Elastic.Apm/Api/Kubernetes/KubernetesMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Apm.Api.Constraints;
using Elastic.Apm.Helpers;
using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;

namespace Elastic.Apm.Api.Kubernetes
{
public class KubernetesMetadata
{
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Namespace { get; set; }

public Node Node { get; set; }
Expand Down
5 changes: 2 additions & 3 deletions src/Elastic.Apm/Api/Kubernetes/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Apm.Api.Constraints;
using Elastic.Apm.Helpers;
using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;

namespace Elastic.Apm.Api.Kubernetes
{
public class Node
{
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Name { get; set; }

public override string ToString() => new ToStringBuilder(nameof(Node)) { { nameof(Name), Name } }.ToString();
Expand Down
7 changes: 3 additions & 4 deletions src/Elastic.Apm/Api/Kubernetes/Pod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Apm.Api.Constraints;
using Elastic.Apm.Helpers;
using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;

namespace Elastic.Apm.Api.Kubernetes
{
public class Pod
{
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Name { get; set; }

[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string Uid { get; set; }

public override string ToString() => new ToStringBuilder(nameof(Pod)) { { nameof(Name), Name }, { nameof(Uid), Uid } }.ToString();
Expand Down
4 changes: 2 additions & 2 deletions src/Elastic.Apm/Api/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Apm.Api.Constraints;
using Elastic.Apm.Helpers;
using Elastic.Apm.Report.Serialization;
using Newtonsoft.Json;

namespace Elastic.Apm.Api
{
public class Node
{
[JsonProperty("configured_name")]
[JsonConverter(typeof(TrimmedStringJsonConverter))]
[MaxLength]
public string ConfiguredName { get; set; }

public override string ToString() => new ToStringBuilder(nameof(Node)) { { nameof(ConfiguredName), ConfiguredName } }.ToString();
Expand Down
Loading

0 comments on commit a4b5c33

Please sign in to comment.