Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add custom #118

Closed
wants to merge 18 commits into from
11 changes: 11 additions & 0 deletions src/Elastic.Apm/Api/IRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Elastic.Apm.Model.Payload;

namespace Elastic.Apm.Api
{
public interface IRequest
{
string HttpVersion { get; set; }
string Method { get; set; }
object Body { get; set; }
skynet2 marked this conversation as resolved.
Show resolved Hide resolved
}
}
11 changes: 11 additions & 0 deletions src/Elastic.Apm/Api/ITransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Elastic.Apm.Model.Payload;

namespace Elastic.Apm.Api
{
public interface ITransaction
{
/// <summary>
/// If a log record was generated as a result of a http request, the http interface can be used to collect this information.
/// </summary>
IRequest Request { get; }

/// <summary>
/// User identification
/// </summary>
IUser User { get; }

/// <summary>
/// The duration of the transaction.
/// If it's not set (its HasValue property is false) then the value
Expand Down
9 changes: 9 additions & 0 deletions src/Elastic.Apm/Api/IUser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Elastic.Apm.Api
{
public interface IUser
{
string Id { get; set; }
string Email { get; set; }
string UserName { get; set; }
}
}
2 changes: 2 additions & 0 deletions src/Elastic.Apm/Consts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ internal static class Consts
public static string IntakeV1Errors = "v1/errors";
public static string IntakeV1Transactions = "v1/transactions";

public static readonly int PropertyMaxLength = 1024;

public static string AgentName => "dotNet";
}
}
20 changes: 10 additions & 10 deletions src/Elastic.Apm/Elastic.Apm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@
<PackageTags>apm, monitoring, elastic, elasticapm, analytics, sdk</PackageTags>
</PropertyGroup>
<ItemGroup>
<Folder Include="Report\"/>
skynet2 marked this conversation as resolved.
Show resolved Hide resolved
<Folder Include="DiagnosticSource\"/>
<Folder Include="DiagnosticListeners\"/>
<Folder Include="Logging\"/>
<Folder Include="Config\"/>
<Folder Include="Helpers\"/>
<Folder Include="Api\"/>
<Folder Include="Report\" />
<Folder Include="DiagnosticSource\" />
<Folder Include="DiagnosticListeners\" />
<Folder Include="Logging\" />
<Folder Include="Config\" />
<Folder Include="Helpers\" />
<Folder Include="Api\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2"/>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<!-- TODO: Are we ok with this reference/version? -->
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.0.0"/>
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.9.0"/>
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.0.0" />
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.9.0" />
</ItemGroup>
</Project>
18 changes: 18 additions & 0 deletions src/Elastic.Apm/Helpers/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Elastic.Apm.Helpers
{
internal static class StringExtensions
skynet2 marked this conversation as resolved.
Show resolved Hide resolved
{
internal static string TrimToLength(this string input, int maxLength)
skynet2 marked this conversation as resolved.
Show resolved Hide resolved
{
if (input.Length > maxLength)
input = $"{input.Substring(0, Consts.PropertyMaxLength-3)}...";

return input;
}

internal static string TrimToMaxLength(this string input)
skynet2 marked this conversation as resolved.
Show resolved Hide resolved
{
return input.TrimToLength(Consts.PropertyMaxLength);
}
}
}
25 changes: 21 additions & 4 deletions src/Elastic.Apm/Model/Payload/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,28 @@ namespace Elastic.Apm.Model.Payload
{
internal class Context
{
private readonly Lazy<Dictionary<string, string>> tags = new Lazy<Dictionary<string, string>>();
public Request Request { get; set; }
private readonly Lazy<Dictionary<string, string>> _tags = new Lazy<Dictionary<string, string>>();
private Request _request;
private Response _response;
private User _user;

public Response Response { get; set; }
public User User
{
get => _user ?? (_user = new User());
skynet2 marked this conversation as resolved.
Show resolved Hide resolved
set => _user = value;
}
public Request Request
{
get => _request ?? (_request = new Request());
skynet2 marked this conversation as resolved.
Show resolved Hide resolved
set => _request = value;
}

public Dictionary<string, string> Tags => tags.Value;
public Response Response
{
get => _response ?? (_response = new Response());
skynet2 marked this conversation as resolved.
Show resolved Hide resolved
set => _response = value;
}

public Dictionary<string, string> Tags => _tags.Value;
}
}
57 changes: 49 additions & 8 deletions src/Elastic.Apm/Model/Payload/Request.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
using Newtonsoft.Json;
using Elastic.Apm.Api;
using Elastic.Apm.Helpers;
using Newtonsoft.Json;

namespace Elastic.Apm.Model.Payload
{
internal class Request
internal class Request : IRequest
{
public string HttpVersion { get; set; }
private string _httpVersion;
private string _method;

public string HttpVersion
{
get => _httpVersion;
set => _httpVersion = value.TrimToMaxLength();
}

public object Body { get; set; }

public string Method
{
get => _method;
set => _method = value.TrimToMaxLength();
}

public string Method { get; set; }
public Socket Socket { get; set; }
public Url Url { get; set; }
}
Expand All @@ -21,9 +37,34 @@ internal class Socket

internal class Url
{
public string Full { get; set; }
public string HostName { get; set; }
public string Protocol { get; set; }
public string Raw { get; set; }
private string _full;
private string _raw;
private string _hostName;
private string _protocol;

public string Full
{
get => _full;
set => _full = value.TrimToMaxLength();
}

public string HostName
{
get => _hostName;
set => _hostName = value.TrimToMaxLength();
}

public string Protocol
{
get => _protocol;
set => _protocol = value.TrimToMaxLength();
}


public string Raw
{
get => _raw;
set => _raw = value.TrimToMaxLength();
}
}
}
25 changes: 21 additions & 4 deletions src/Elastic.Apm/Model/Payload/Span.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using Elastic.Apm.Api;
using Elastic.Apm.Helpers;
using Newtonsoft.Json;

namespace Elastic.Apm.Model.Payload
Expand All @@ -24,7 +25,13 @@ public Span(string name, string type, Transaction transaction)
Id = rnd.Next();
}

public string Action { get; set; }
private string _action;

public string Action
{
get => _action;
set => _action = value.TrimToMaxLength();
}

/// <summary>
/// Any other arbitrary data captured by the agent, optionally provided by the user.
Expand All @@ -42,14 +49,25 @@ public Span(string name, string type, Transaction transaction)

public int Id { get; set; }

public string Name { get; set; }
private string _name;
public string Name
{
get => _name;
set => _name = value.TrimToMaxLength();
}

[JsonProperty("Stacktrace")]
public List<Stacktrace> StackTrace { get; set; }

public decimal Start { get; set; }

public string Subtype { get; set; }
private string _subtype;

public string Subtype
{
get => _subtype;
set => _subtype = value.TrimToMaxLength();
}

[JsonIgnore]
public Dictionary<string, string> Tags => Context.Tags;
Expand Down Expand Up @@ -81,7 +99,6 @@ private class ContextImpl : IContext
public Dictionary<string, string> Tags => _tags.Value;
}
}

skynet2 marked this conversation as resolved.
Show resolved Hide resolved
internal interface IContext
{
IDb Db { get; set; }
Expand Down
29 changes: 26 additions & 3 deletions src/Elastic.Apm/Model/Payload/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public Transaction(AbstractLogger logger, string name, string type, IPayloadSend
/// </summary>
public Context Context => _context.Value;

public IRequest Request => _context.Value?.Request;

/// <inheritdoc />
/// <summary>
/// The duration of the transaction.
Expand All @@ -49,15 +51,27 @@ public Transaction(AbstractLogger logger, string name, string type, IPayloadSend

public Guid Id { get; }

public string Name { get; set; }
private string _name;

public string Name
{
get => _name;
set => _name = value.TrimToMaxLength();
}

private string _result;

/// <inheritdoc />
/// <summary>
/// A string describing the result of the transaction.
/// This is typically the HTTP status code, or e.g. "success" for a background task.
/// </summary>
/// <value>The result.</value>
public string Result { get; set; }
public string Result
{
get => _result;
set => _result = value.TrimToMaxLength();
}

internal Service Service;

Expand All @@ -70,9 +84,18 @@ public Transaction(AbstractLogger logger, string name, string type, IPayloadSend
[JsonIgnore]
public Dictionary<string, string> Tags => Context.Tags;

[JsonIgnore]
public IUser User => Context.User;

public string Timestamp => Start.ToString("yyyy-MM-ddTHH:mm:ss.FFFZ");

public string Type { get; set; }
private string _type;

public string Type
{
get => _type;
set => _type = value.TrimToMaxLength();
}

public void End()
{
Expand Down
32 changes: 32 additions & 0 deletions src/Elastic.Apm/Model/Payload/User.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Elastic.Apm.Api;
using Elastic.Apm.Helpers;

namespace Elastic.Apm.Model.Payload
{
internal class User : IUser
{
private string _id;
private string _userName;
private string _email;

public string Id
{
get => _id;
set => _id = value.TrimToMaxLength();
}


public string Email
{
get => _email;
set => _email = value.TrimToMaxLength();
}


public string UserName
{
get => _userName;
set => _userName = value.TrimToMaxLength();
}
}
}
7 changes: 6 additions & 1 deletion src/Elastic.Apm/Report/PayloadSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@ private async void StartWork()
break;
}

// TODO: handle unsuccesful status codes
if (result != null && !result.IsSuccessStatusCode)
{
var str = await result.Content.ReadAsStringAsync();

_logger.LogError($"Failed sending transaction. {str}");
}
}
catch (Exception e)
{
Expand Down
Loading