├── .gitignore ├── Demo ├── Demo.dpr ├── uMain.dfm └── uMain.pas ├── LICENSE ├── README.md ├── delphiDatadog.event.pas ├── delphiDatadog.header.pas ├── delphiDatadog.serviceCheck.pas ├── delphiDatadog.statsDClient.impl.pas ├── delphiDatadog.statsDClient.interf.pas ├── delphiDatadog.statsDClientSender.impl.pas ├── delphiDatadog.statsDClientSender.interf.pas └── delphiDatadog.utils.pas /.gitignore: -------------------------------------------------------------------------------- 1 | # Uncomment these types if you want even more clean repository. But be careful. 2 | # It can make harm to an existing project source. Read explanations below. 3 | # 4 | # Resource files are binaries containing manifest, project icon and version info. 5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. 6 | #*.res 7 | # 8 | # Type library file (binary). In old Delphi versions it should be stored. 9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored. 10 | #*.tlb 11 | # 12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7. 13 | # Uncomment this if you are not using diagrams or use newer Delphi version. 14 | #*.ddp 15 | # 16 | # Visual LiveBindings file. Added in Delphi XE2. 17 | # Uncomment this if you are not using LiveBindings Designer. 18 | #*.vlb 19 | # 20 | # Deployment Manager configuration file for your project. Added in Delphi XE2. 21 | # Uncomment this if it is not mobile development and you do not use remote debug feature. 22 | #*.deployproj 23 | # 24 | # C++ object files produced when C/C++ Output file generation is configured. 25 | # Uncomment this if you are not using external objects (zlib library for example). 26 | #*.obj 27 | # 28 | 29 | # Delphi compiler-generated binaries (safe to delete) 30 | *.exe 31 | *.dll 32 | *.bpl 33 | *.bpi 34 | *.dcp 35 | *.so 36 | *.apk 37 | *.drc 38 | *.map 39 | *.dres 40 | *.rsm 41 | *.tds 42 | *.dcu 43 | *.lib 44 | *.a 45 | *.o 46 | *.ocx 47 | 48 | # Delphi autogenerated files (duplicated info) 49 | *.cfg 50 | *.hpp 51 | *Resource.rc 52 | 53 | # Delphi local files (user-specific info) 54 | *.local 55 | *.identcache 56 | *.projdata 57 | *.tvsconfig 58 | *.dsk 59 | 60 | # Delphi history and backups 61 | __history/ 62 | __recovery/ 63 | *.~* 64 | 65 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi) 66 | *.stat 67 | -------------------------------------------------------------------------------- /Demo/Demo.dpr: -------------------------------------------------------------------------------- 1 | program Demo; 2 | 3 | uses 4 | Vcl.Forms, 5 | uMain in 'uMain.pas' {frmDemo}, 6 | delphiDatadog.event in '..\delphiDatadog.event.pas', 7 | delphiDatadog.header in '..\delphiDatadog.header.pas', 8 | delphiDatadog.serviceCheck in '..\delphiDatadog.serviceCheck.pas', 9 | delphiDatadog.statsDClient.impl in '..\delphiDatadog.statsDClient.impl.pas', 10 | delphiDatadog.statsDClient.interf in '..\delphiDatadog.statsDClient.interf.pas', 11 | delphiDatadog.statsDClientSender.impl in '..\delphiDatadog.statsDClientSender.impl.pas', 12 | delphiDatadog.statsDClientSender.interf in '..\delphiDatadog.statsDClientSender.interf.pas', 13 | delphiDatadog.utils in '..\delphiDatadog.utils.pas'; 14 | 15 | {$R *.res} 16 | 17 | begin 18 | Application.Initialize; 19 | Application.MainFormOnTaskbar := True; 20 | Application.CreateForm(TfrmDemo, frmDemo); 21 | Application.Run; 22 | end. 23 | -------------------------------------------------------------------------------- /Demo/uMain.dfm: -------------------------------------------------------------------------------- 1 | object frmDemo: TfrmDemo 2 | Left = 0 3 | Top = 0 4 | Caption = 'Demo' 5 | ClientHeight = 92 6 | ClientWidth = 619 7 | Color = clBtnFace 8 | Font.Charset = DEFAULT_CHARSET 9 | Font.Color = clWindowText 10 | Font.Height = -11 11 | Font.Name = 'Tahoma' 12 | Font.Style = [] 13 | OldCreateOrder = False 14 | OnCreate = FormCreate 15 | PixelsPerInch = 96 16 | TextHeight = 13 17 | object btnSendMetrics: TButton 18 | Left = 54 19 | Top = 19 20 | Width = 131 21 | Height = 25 22 | Caption = 'Send Metrics' 23 | TabOrder = 0 24 | OnClick = btnSendMetricsClick 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /Demo/uMain.pas: -------------------------------------------------------------------------------- 1 | unit uMain; 2 | 3 | interface 4 | 5 | uses 6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 7 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, delphiDatadog.statsDClient.interf; 8 | 9 | type 10 | TfrmDemo = class(TForm) 11 | btnSendMetrics: TButton; 12 | procedure btnSendMetricsClick(Sender: TObject); 13 | procedure FormCreate(Sender: TObject); 14 | private 15 | StatsDClient: IDataDogStatsClient; 16 | { Private declarations } 17 | public 18 | { Public declarations } 19 | end; 20 | 21 | var 22 | frmDemo: TfrmDemo; 23 | 24 | implementation 25 | 26 | uses 27 | delphiDatadog.statsDClient.impl, delphiDatadog.statsDClientSender.impl, delphiDatadog.serviceCheck, 28 | delphiDatadog.statsDClientSender.interf, delphiDatadog.header, delphiDatadog.event; 29 | 30 | {$R *.dfm} 31 | 32 | procedure TfrmDemo.btnSendMetricsClick(Sender: TObject); 33 | var 34 | Event: TDataDogEvent; 35 | begin 36 | StatsDClient.Count('qtt', 1, TDataDogTags.Create('mob', 'foo')); 37 | StatsDClient.RecordExecutionTime('testBM', Random(500), TDataDogTags.Create('valueX')); 38 | 39 | Event := TDataDogEvent.Create; 40 | Event.Title := 'Error on report'; 41 | Event.Text := 'Error while trying to translate the report'; 42 | Event.Priority := ddLow; 43 | Event.AlertType := ddError; 44 | StatsDClient.RecordEvent(Event, TDataDogTags.Create('eventTest')); 45 | Event.Free; 46 | end; 47 | 48 | procedure TfrmDemo.FormCreate(Sender: TObject); 49 | var 50 | SenderStatsDClient: IDataDogStatsClientSender; 51 | DataDogService: TDataDogServiceCheck; 52 | begin 53 | DataDogService := TDataDogServiceCheck.Create; 54 | SenderStatsDClient := TDataDogStatsClientSender.Create(DataDogService); 55 | StatsDClient := TDataDogStatsClientImpl.Create(SenderStatsDClient); 56 | end; 57 | 58 | end. 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Rodrigo Farias Rezino 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # datadog-delphi 2 | 3 | A statsd client library implemented in Delphi. Allows for Java applications to easily communicate with statsd. 4 | 5 | Version 1.0! 6 | 7 | Check the demo to see how does it works :) 8 | 9 | [https://www.datadoghq.com/](https://www.datadoghq.com/) 10 | 11 |
12 |
13 |
14 | 15 | This package is provided by **Coolblue** :D 16 | 17 | More information [http://www.careersatcoolblue.com/](http://www.careersatcoolblue.com/) -------------------------------------------------------------------------------- /delphiDatadog.event.pas: -------------------------------------------------------------------------------- 1 | unit delphiDatadog.event; 2 | 3 | interface 4 | 5 | uses 6 | delphiDatadog.header; 7 | 8 | type 9 | TDataDogEvent = class(TObject) 10 | private 11 | FTitle: string; 12 | FText: string; 13 | FMillisSinceEpoch: Int64; 14 | FHostName: string; 15 | FAggregationKey: string; 16 | FPriority: TDataDogEventPriority; 17 | FSourcerTypeName: string; 18 | FAlertType: TDataDogEventAlertType; 19 | public 20 | function ToMap: string; 21 | 22 | property Title: string read FTitle write FTitle; 23 | property Text: string read FText write FText; 24 | property MillisSinceEpoch: Int64 read FMillisSinceEpoch write FMillisSinceEpoch; 25 | property HostName: string read FHostName write FHostName; 26 | property AggregationKey: string read FAggregationKey write FAggregationKey; 27 | property Priority: TDataDogEventPriority read FPriority write FPriority; 28 | property SourcerTypeName: string read FSourcerTypeName write FSourcerTypeName; 29 | property AlertType: TDataDogEventAlertType read FAlertType write FAlertType; 30 | end; 31 | 32 | implementation 33 | 34 | uses 35 | System.SysUtils, delphiDatadog.utils; 36 | 37 | { TDataDogEvent } 38 | 39 | function TDataDogEvent.ToMap: string; 40 | var 41 | MapParams: TStringBuilder; 42 | DoubleResult: Double; 43 | PriorityText: string; 44 | AlertText: string; 45 | begin 46 | MapParams := TStringBuilder.Create; 47 | try 48 | if (MillisSinceEpoch <> 0) then 49 | begin 50 | DoubleResult := MillisSinceEpoch / 1000; 51 | MapParams.Append('|d:').Append(DoubleResult); 52 | end; 53 | 54 | if not HostName.IsEmpty then 55 | MapParams.Append('|h:').Append(HostName); 56 | 57 | if not AggregationKey.IsEmpty then 58 | MapParams.Append('|k:').Append(AggregationKey); 59 | 60 | PriorityText := DataTagsEventPriorityToText(Priority); 61 | if not PriorityText.IsEmpty then 62 | MapParams.Append('|p:').Append(PriorityText); 63 | 64 | AlertText := DataTagsEventAlertToText(AlertType); 65 | if not AlertText.IsEmpty then 66 | MapParams.Append('|t:').Append(AlertText); 67 | 68 | Result := MapParams.ToString; 69 | finally 70 | MapParams.Free; 71 | end; 72 | end; 73 | 74 | end. 75 | -------------------------------------------------------------------------------- /delphiDatadog.header.pas: -------------------------------------------------------------------------------- 1 | unit delphiDatadog.header; 2 | 3 | interface 4 | 5 | type 6 | TDataDogTag = string; 7 | TDataDogAspect = string; 8 | 9 | TDataDogTags = TArray; 10 | 11 | TDataDogEventPriority = (ddLow, ddNormal); 12 | 13 | TDataDogEventAlertType = (ddError, ddWarning, ddInfo, ddSuccess, ddUndefined); 14 | 15 | TDataDogServiceStatus = (dssOK = 0, dssWarning = 1, dssCritical = 2, dssUnknown = 3, dssUndefined = 4); 16 | 17 | implementation 18 | 19 | end. 20 | -------------------------------------------------------------------------------- /delphiDatadog.serviceCheck.pas: -------------------------------------------------------------------------------- 1 | unit delphiDatadog.serviceCheck; 2 | 3 | interface 4 | 5 | uses 6 | delphiDatadog.header; 7 | 8 | type 9 | TDataDogServiceCheck = class(TObject) 10 | private 11 | FName: string; 12 | FHostname: string; 13 | FStatus: TDataDogServiceStatus; 14 | FRunId: Integer; 15 | FTimeStamp: Cardinal; 16 | FTags: TDataDogTags; 17 | FMessageText: string; 18 | FPort: Integer; 19 | procedure SetHostname(const Value: string); 20 | procedure SetPort(const Value: Integer); 21 | public 22 | constructor Create; 23 | 24 | function ToStatsDString: string; 25 | 26 | property Name: string read FName write FName; 27 | property Hostname: string read FHostname write SetHostname; 28 | property Port: Integer read FPort write SetPort; 29 | property Status: TDataDogServiceStatus read FStatus write FStatus; 30 | property MessageText: string read FMessageText write FMessageText; 31 | property RunId: Integer read FRunId write FRunId; 32 | property TimeStamp: Cardinal read FTimeStamp write FTimeStamp; 33 | property Tags: TDataDogTags read FTags write FTags; 34 | end; 35 | 36 | implementation 37 | 38 | uses 39 | System.SysUtils, delphiDatadog.utils; 40 | 41 | const 42 | STAND_PORT = 8125; 43 | STAND_HOST = 'localhost'; 44 | 45 | { TDataDogServiceCheck } 46 | 47 | constructor TDataDogServiceCheck.Create; 48 | begin 49 | FHostname := STAND_HOST; 50 | FStatus := dssUndefined; 51 | FPort := STAND_PORT; 52 | end; 53 | 54 | procedure TDataDogServiceCheck.SetHostname(const Value: string); 55 | begin 56 | if Value.IsEmpty then 57 | FHostname := STAND_HOST 58 | else 59 | FHostname := Value; 60 | end; 61 | 62 | procedure TDataDogServiceCheck.SetPort(const Value: Integer); 63 | begin 64 | if Value = 0 then 65 | FPort := STAND_PORT 66 | else 67 | FPort := Value; 68 | end; 69 | 70 | function TDataDogServiceCheck.ToStatsDString: string; 71 | var 72 | StatsString: TStringBuilder; 73 | begin 74 | StatsString := TStringBuilder.Create; 75 | 76 | StatsString.Append(Format('_sc|%s|%d', [Name, Ord(Status)])); 77 | if (Timestamp > 0) then 78 | StatsString.Append(Format('|d:%d', [Timestamp])); 79 | 80 | if not (HostName.IsEmpty) then 81 | StatsString.Append(Format('|h:%s', [Hostname])); 82 | 83 | StatsString.Append(DataTagsToText(Tags)); 84 | if (not MessageText.IsEmpty) then 85 | StatsString.Append(Format('|m:%s', [EscapedMessage(MessageText)])); 86 | 87 | Result := StatsString.ToString; 88 | StatsString.Free; 89 | end; 90 | 91 | end. 92 | -------------------------------------------------------------------------------- /delphiDatadog.statsDClient.impl.pas: -------------------------------------------------------------------------------- 1 | unit delphiDatadog.statsDClient.impl; 2 | 3 | interface 4 | 5 | uses 6 | delphiDatadog.statsDClient.interf, delphiDatadog.header, delphiDatadog.serviceCheck, 7 | delphiDatadog.event, delphiDatadog.statsDClientSender.interf; 8 | 9 | type 10 | TDataDogStatsClientImpl = class(TInterfacedObject, IDataDogStatsClient) 11 | private 12 | FPrefix: string; 13 | FSender: IDataDogStatsClientSender; 14 | 15 | procedure Send(Content: string); 16 | function IsInvalidSample(Sample: Double): Boolean; 17 | 18 | function GetPrefix: string; 19 | procedure SetPrefix(Value: string); 20 | public 21 | constructor Create(var Sender: IDataDogStatsClientSender); 22 | destructor Destroy; override; 23 | 24 | procedure Count(Aspect: TDataDogAspect; Delta: Int64; Tags: TDataDogTags); overload; 25 | procedure Count(Aspect: TDataDogAspect; Delta: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 26 | procedure IncrementCounter(Aspect: TDataDogAspect; Tags: TDataDogTags); overload; 27 | procedure IncrementCounter(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); overload; 28 | procedure Increment(Aspect: TDataDogAspect; Tags: TDataDogTags); overload; 29 | procedure Increment(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); overload; 30 | procedure DecrementCounter(Aspect: TDataDogAspect; Tags: TDataDogTags); overload; 31 | procedure DecrementCounter(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); overload; 32 | procedure Decrement(Aspect: TDataDogAspect; Tags: TDataDogTags); overload; 33 | procedure Decrement(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); overload; 34 | procedure RecordGaugeValue(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); overload; 35 | procedure RecordGaugeValue(Aspect: TDataDogAspect; Value: Double; SampleRate: Double; Tags: TDataDogTags); overload; 36 | procedure Gauge(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); overload; 37 | procedure Gauge(Aspect: TDataDogAspect; Value: Double; SampleRate: Double; Tags: TDataDogTags); overload; 38 | procedure RecordGaugeValue(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 39 | procedure RecordGaugeValue(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 40 | procedure Gauge(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 41 | procedure Gauge(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 42 | procedure RecordExecutionTime(Aspect: TDataDogAspect; TimeInMs: Int64; Tags: TDataDogTags); overload; 43 | procedure RecordExecutionTime(Aspect: TDataDogAspect; TimeInMs: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 44 | procedure Time(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 45 | procedure Time(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 46 | procedure RecordHistogramValue(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); overload; 47 | procedure RecordHistogramValue(Aspect: TDataDogAspect; Value: Double; SampleRate: Double; Tags: TDataDogTags); overload; 48 | procedure Histogram(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); overload; 49 | procedure Histogram(Aspect: TDataDogAspect; Value: Double; SampleRate: Double; Tags: TDataDogTags); overload; 50 | procedure RecordHistogramValue(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 51 | procedure RecordHistogramValue(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 52 | procedure Histogram(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 53 | procedure Histogram(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 54 | procedure RecordEvent(Event: TDataDogEvent; Tags: TDataDogTags); overload; 55 | procedure RecordSetValue(Aspect: TDataDogAspect; Value: string; Tags: TDataDogTags); overload; 56 | 57 | property Prefix: string read GetPrefix write SetPrefix; 58 | end; 59 | 60 | implementation 61 | 62 | uses 63 | System.SysUtils, delphiDatadog.utils; 64 | 65 | var 66 | DatadogFormatSettings: TFormatSettings; 67 | 68 | { TDataDogStatsClientImpl } 69 | 70 | procedure TDataDogStatsClientImpl.Count(Aspect: TDataDogAspect; Delta: Int64; Tags: TDataDogTags); 71 | begin 72 | Send(Format('%s%s:%d|c%s', [Prefix, Aspect, Delta, DataTagsToText(Tags)])); 73 | end; 74 | 75 | procedure TDataDogStatsClientImpl.Count(Aspect: TDataDogAspect; Delta: Int64; SampleRate: Double; Tags: TDataDogTags); 76 | begin 77 | if not (IsInvalidSample(SampleRate)) then Exit; 78 | 79 | Send(Format('%s%s:%d|c|%f%s', [Prefix, Aspect, Delta, sampleRate, DataTagsToText(Tags)])); 80 | end; 81 | 82 | constructor TDataDogStatsClientImpl.Create(var Sender: IDataDogStatsClientSender); 83 | begin 84 | FSender := Sender; 85 | end; 86 | 87 | procedure TDataDogStatsClientImpl.Decrement(Aspect: TDataDogAspect; Tags: TDataDogTags); 88 | begin 89 | DecrementCounter(Aspect, Tags); 90 | end; 91 | 92 | procedure TDataDogStatsClientImpl.Decrement(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); 93 | begin 94 | DecrementCounter(Aspect, SampleRate, Tags); 95 | end; 96 | 97 | procedure TDataDogStatsClientImpl.DecrementCounter(Aspect: TDataDogAspect; Tags: TDataDogTags); 98 | begin 99 | Count(Aspect, -1, Tags); 100 | end; 101 | 102 | procedure TDataDogStatsClientImpl.DecrementCounter(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); 103 | begin 104 | Count(Aspect, -1, SampleRate, Tags); 105 | end; 106 | 107 | destructor TDataDogStatsClientImpl.Destroy; 108 | begin 109 | 110 | inherited; 111 | end; 112 | 113 | procedure TDataDogStatsClientImpl.Gauge(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); 114 | begin 115 | Send(Format('%s%s:%d|g%s', [Prefix, Aspect, Value, DataTagsToText(Tags)])); 116 | end; 117 | 118 | procedure TDataDogStatsClientImpl.Gauge(Aspect: TDataDogAspect; Value, SampleRate: Double; Tags: TDataDogTags); 119 | begin 120 | RecordGaugeValue(Aspect, Value, SampleRate, Tags); 121 | end; 122 | 123 | procedure TDataDogStatsClientImpl.Gauge(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); 124 | begin 125 | RecordGaugeValue(Aspect, Value, Tags); 126 | end; 127 | 128 | procedure TDataDogStatsClientImpl.Gauge(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); 129 | begin 130 | RecordGaugeValue(Aspect, Value, SampleRate, Tags); 131 | end; 132 | 133 | function TDataDogStatsClientImpl.GetPrefix: string; 134 | begin 135 | Result := FPrefix; 136 | end; 137 | 138 | procedure TDataDogStatsClientImpl.Histogram(Aspect: TDataDogAspect; Value, SampleRate: Double; Tags: TDataDogTags); 139 | begin 140 | RecordHistogramValue(Aspect, Value, SampleRate, Tags); 141 | end; 142 | 143 | procedure TDataDogStatsClientImpl.Histogram(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); 144 | begin 145 | RecordHistogramValue(Aspect, Value, Tags); 146 | end; 147 | 148 | procedure TDataDogStatsClientImpl.Histogram(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); 149 | begin 150 | RecordHistogramValue(Aspect, Value, Tags); 151 | end; 152 | 153 | procedure TDataDogStatsClientImpl.Histogram(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); 154 | begin 155 | RecordHistogramValue(Aspect, Value, SampleRate, Tags); 156 | end; 157 | 158 | procedure TDataDogStatsClientImpl.Increment(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); 159 | begin 160 | IncrementCounter(Aspect, SampleRate, Tags); 161 | end; 162 | 163 | procedure TDataDogStatsClientImpl.Increment(Aspect: TDataDogAspect; Tags: TDataDogTags); 164 | begin 165 | IncrementCounter(Aspect, Tags); 166 | end; 167 | 168 | procedure TDataDogStatsClientImpl.IncrementCounter(Aspect: TDataDogAspect; Tags: TDataDogTags); 169 | begin 170 | Count(Aspect, 1, Tags); 171 | end; 172 | 173 | procedure TDataDogStatsClientImpl.IncrementCounter(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); 174 | begin 175 | Count(Aspect, 1, SampleRate, Tags); 176 | end; 177 | 178 | function TDataDogStatsClientImpl.IsInvalidSample(Sample: Double): Boolean; 179 | begin 180 | Result := True; 181 | end; 182 | 183 | procedure TDataDogStatsClientImpl.RecordEvent(Event: TDataDogEvent; Tags: TDataDogTags); 184 | var 185 | Title: string; 186 | Text: string; 187 | begin 188 | Title := EscapedMessage(Prefix + Event.Title); 189 | Text := EscapedMessage(Event.Text); 190 | 191 | Send(Format('_e{%d,%d}:%s|%s%s%s', [Title.Length, Text.Length, Title, Text, Event.ToMap, DataTagsToText(Tags)])); 192 | end; 193 | 194 | procedure TDataDogStatsClientImpl.RecordExecutionTime(Aspect: TDataDogAspect; TimeInMs: Int64; SampleRate: Double; Tags: TDataDogTags); 195 | begin 196 | if(IsInvalidSample(SampleRate)) then Exit; 197 | 198 | Send(Format('%s%s:%d|ms|%f%s', [Prefix, Aspect, TimeInMs, SampleRate, DataTagsToText(Tags)])); 199 | end; 200 | 201 | procedure TDataDogStatsClientImpl.RecordExecutionTime(Aspect: TDataDogAspect; TimeInMs: Int64; Tags: TDataDogTags); 202 | begin 203 | Send(Format('%s%s:%d|ms%s', [Prefix, Aspect, TimeInMs, DataTagsToText(Tags)])); 204 | end; 205 | 206 | procedure TDataDogStatsClientImpl.RecordGaugeValue(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); 207 | begin 208 | Send(Format('%s%s:%d|g%s', [Prefix, Aspect, Value, DataTagsToText(tags)])); 209 | end; 210 | 211 | procedure TDataDogStatsClientImpl.RecordGaugeValue(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); 212 | begin 213 | Send(Format('%s%s:%s|g%s', [Prefix, Aspect, FloatToStr(Value, DatadogFormatSettings), DataTagsToText(Tags)])); 214 | end; 215 | 216 | procedure TDataDogStatsClientImpl.RecordGaugeValue(Aspect: TDataDogAspect; Value, SampleRate: Double; Tags: TDataDogTags); 217 | begin 218 | Send(Format('%s%s:%s|g|%f%s', [Prefix, Aspect, FloatToStr(Value, DatadogFormatSettings), SampleRate, DataTagsToText(Tags)])); 219 | end; 220 | 221 | procedure TDataDogStatsClientImpl.RecordGaugeValue(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); 222 | begin 223 | if not (IsInvalidSample(SampleRate)) then Exit; 224 | 225 | Send(Format('%s%s:%d|g|%f%s', [Prefix, Aspect, Value, SampleRate, DataTagsToText(Tags)])); 226 | end; 227 | 228 | procedure TDataDogStatsClientImpl.RecordHistogramValue(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); 229 | begin 230 | Send(Format('%s%s:%d|h%s', [Prefix, Aspect, Value, DataTagsToText(Tags)])); 231 | end; 232 | 233 | procedure TDataDogStatsClientImpl.RecordHistogramValue(Aspect: TDataDogAspect; Value, SampleRate: Double; Tags: TDataDogTags); 234 | begin 235 | if(IsInvalidSample(SampleRate)) then Exit; 236 | 237 | Send(Format('%s%s:%s|h|%f%s', [Prefix, Aspect, FloatToStr(Value, DatadogFormatSettings), SampleRate, DataTagsToText(Tags)])); 238 | end; 239 | 240 | procedure TDataDogStatsClientImpl.RecordHistogramValue(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); 241 | begin 242 | Send(Format('%s%s:%s|h%s', [Prefix, Aspect, FloatToStr(Value, DatadogFormatSettings), DataTagsToText(Tags)])); 243 | end; 244 | 245 | procedure TDataDogStatsClientImpl.RecordHistogramValue(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); 246 | begin 247 | if(isInvalidSample(SampleRate)) then Exit; 248 | 249 | Send(Format('%s%s:%d|h|%f%s', [Prefix, Aspect, Value, SampleRate, DataTagsToText(Tags)])); 250 | end; 251 | 252 | procedure TDataDogStatsClientImpl.RecordSetValue(Aspect: TDataDogAspect; Value: string; Tags: TDataDogTags); 253 | begin 254 | Send(Format('%s%s:%s|s%s', [Prefix, Aspect, Value, DataTagsToText(Tags)])); 255 | end; 256 | 257 | procedure TDataDogStatsClientImpl.Send(Content: string); 258 | begin 259 | FSender.Send(Content); 260 | end; 261 | 262 | procedure TDataDogStatsClientImpl.SetPrefix(Value: string); 263 | begin 264 | FPrefix := Value; 265 | end; 266 | 267 | procedure TDataDogStatsClientImpl.Time(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); 268 | begin 269 | RecordExecutionTime(Aspect, Value, SampleRate, Tags); 270 | end; 271 | 272 | procedure TDataDogStatsClientImpl.Time(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); 273 | begin 274 | RecordExecutionTime(Aspect, Value, Tags); 275 | end; 276 | 277 | end. 278 | -------------------------------------------------------------------------------- /delphiDatadog.statsDClient.interf.pas: -------------------------------------------------------------------------------- 1 | unit delphiDatadog.statsDClient.interf; 2 | 3 | interface 4 | 5 | uses 6 | delphiDatadog.header, delphiDatadog.serviceCheck, delphiDatadog.event; 7 | 8 | type 9 | 10 | IDataDogStatsClient = interface(IInterface) 11 | procedure Count(Aspect: TDataDogAspect; Delta: Int64; Tags: TDataDogTags); overload; 12 | procedure Count(Aspect: TDataDogAspect; Delta: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 13 | procedure IncrementCounter(Aspect: TDataDogAspect; Tags: TDataDogTags); overload; 14 | procedure IncrementCounter(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); overload; 15 | procedure Increment(Aspect: TDataDogAspect; Tags: TDataDogTags); overload; 16 | procedure Increment(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); overload; 17 | procedure DecrementCounter(Aspect: TDataDogAspect; Tags: TDataDogTags); overload; 18 | procedure DecrementCounter(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); overload; 19 | procedure Decrement(Aspect: TDataDogAspect; Tags: TDataDogTags); overload; 20 | procedure Decrement(Aspect: TDataDogAspect; SampleRate: Double; Tags: TDataDogTags); overload; 21 | procedure RecordGaugeValue(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); overload; 22 | procedure RecordGaugeValue(Aspect: TDataDogAspect; Value: Double; SampleRate: Double; Tags: TDataDogTags); overload; 23 | procedure Gauge(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); overload; 24 | procedure Gauge(Aspect: TDataDogAspect; Value: Double; SampleRate: Double; Tags: TDataDogTags); overload; 25 | procedure RecordGaugeValue(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 26 | procedure RecordGaugeValue(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 27 | procedure Gauge(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 28 | procedure Gauge(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 29 | procedure RecordExecutionTime(Aspect: TDataDogAspect; TimeInMs: Int64; Tags: TDataDogTags); overload; 30 | procedure RecordExecutionTime(Aspect: TDataDogAspect; TimeInMs: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 31 | procedure Time(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 32 | procedure Time(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 33 | procedure RecordHistogramValue(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); overload; 34 | procedure RecordHistogramValue(Aspect: TDataDogAspect; Value: Double; SampleRate: Double; Tags: TDataDogTags); overload; 35 | procedure Histogram(Aspect: TDataDogAspect; Value: Double; Tags: TDataDogTags); overload; 36 | procedure Histogram(Aspect: TDataDogAspect; Value: Double; SampleRate: Double; Tags: TDataDogTags); overload; 37 | procedure RecordHistogramValue(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 38 | procedure RecordHistogramValue(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 39 | procedure Histogram(Aspect: TDataDogAspect; Value: Int64; Tags: TDataDogTags); overload; 40 | procedure Histogram(Aspect: TDataDogAspect; Value: Int64; SampleRate: Double; Tags: TDataDogTags); overload; 41 | procedure RecordEvent(Event: TDataDogEvent; Tags: TDataDogTags); overload; 42 | procedure RecordSetValue(Aspect: TDataDogAspect; Value: string; Tags: TDataDogTags); overload; 43 | 44 | function GetPrefix: string; 45 | procedure SetPrefix(Value: string); 46 | end; 47 | 48 | 49 | implementation 50 | 51 | end. 52 | -------------------------------------------------------------------------------- /delphiDatadog.statsDClientSender.impl.pas: -------------------------------------------------------------------------------- 1 | unit delphiDatadog.statsDClientSender.impl; 2 | 3 | interface 4 | 5 | uses 6 | delphiDatadog.statsDClientSender.interf, System.SyncObjs, System.Classes, delphiDatadog.serviceCheck, 7 | IdUDPClient; 8 | 9 | type 10 | TDataDogStatsClientSender = class(TInterfacedObject, IDataDogStatsClientSender) 11 | private type 12 | 13 | TDatadogThreadSender = class(TThread) 14 | private 15 | FUDPCom: TIdUDPClient; 16 | FRcMessages: TCriticalSection; 17 | FMessages: TStringList; 18 | FService: TDataDogServiceCheck; 19 | protected 20 | procedure Execute; override; 21 | 22 | procedure SendMessages; 23 | procedure ConfigureUDP; 24 | function GetMessagesToSend: TStringList; 25 | public 26 | constructor Create(Service: TDataDogServiceCheck); 27 | destructor Destroy; override; 28 | 29 | procedure Send(Content: string); 30 | end; 31 | 32 | private 33 | FSender: TDatadogThreadSender; 34 | public 35 | constructor Create(Service: TDataDogServiceCheck); 36 | destructor Destroy; override; 37 | 38 | procedure Send(Content: string); 39 | end; 40 | 41 | implementation 42 | 43 | { TDataDogStatsClientSender } 44 | 45 | constructor TDataDogStatsClientSender.Create(Service: TDataDogServiceCheck); 46 | begin 47 | inherited Create; 48 | FSender := TDatadogThreadSender.Create(Service); 49 | FSender.Start; 50 | end; 51 | 52 | destructor TDataDogStatsClientSender.Destroy; 53 | begin 54 | FSender.Terminate; 55 | inherited; 56 | end; 57 | 58 | procedure TDataDogStatsClientSender.Send(Content: string); 59 | begin 60 | FSender.Send(Content); 61 | end; 62 | 63 | { TDataDogStatsClientSender.TDatadogThreadSender } 64 | 65 | procedure TDataDogStatsClientSender.TDatadogThreadSender.ConfigureUDP; 66 | begin 67 | FUDPCom.Port := FService.Port; 68 | FUDPCom.Host := FService.Hostname; 69 | end; 70 | 71 | constructor TDataDogStatsClientSender.TDatadogThreadSender.Create(Service: TDataDogServiceCheck); 72 | begin 73 | inherited Create(True); 74 | FreeOnTerminate := True; 75 | 76 | FRcMessages := TCriticalSection.Create; 77 | FService := Service; 78 | FMessages := TStringList.Create; 79 | FUDPCom := TIdUDPClient.Create(nil); 80 | end; 81 | 82 | destructor TDataDogStatsClientSender.TDatadogThreadSender.Destroy; 83 | begin 84 | FUDPCom.Free; 85 | FMessages.Free; 86 | FRcMessages.Free; 87 | inherited; 88 | end; 89 | 90 | procedure TDataDogStatsClientSender.TDatadogThreadSender.Execute; 91 | begin 92 | while not Terminated do 93 | begin 94 | if FMessages.Count > 0 then 95 | SendMessages; 96 | Sleep(500); 97 | end; 98 | end; 99 | 100 | function TDataDogStatsClientSender.TDatadogThreadSender.GetMessagesToSend: TStringList; 101 | begin 102 | FRcMessages.Acquire; 103 | try 104 | Result := FMessages; 105 | FMessages := TStringList.Create; 106 | finally 107 | FRcMessages.Release; 108 | end; 109 | end; 110 | 111 | procedure TDataDogStatsClientSender.TDatadogThreadSender.Send(Content: string); 112 | begin 113 | FRcMessages.Acquire; 114 | try 115 | FMessages.Add(Content); 116 | finally 117 | FRcMessages.Release; 118 | end; 119 | end; 120 | 121 | procedure TDataDogStatsClientSender.TDatadogThreadSender.SendMessages; 122 | var 123 | MessagensToSend: TStringList; 124 | MessageTxt: string; 125 | begin 126 | ConfigureUDP; 127 | MessagensToSend := GetMessagesToSend; 128 | try 129 | for MessageTxt in MessagensToSend do 130 | FUDPCom.Send(MessageTxt); 131 | finally 132 | MessagensToSend.Free; 133 | end; 134 | end; 135 | 136 | end. 137 | -------------------------------------------------------------------------------- /delphiDatadog.statsDClientSender.interf.pas: -------------------------------------------------------------------------------- 1 | unit delphiDatadog.statsDClientSender.interf; 2 | 3 | interface 4 | 5 | type 6 | IDataDogStatsClientSender = interface(IInterface) 7 | procedure Send(Content: string); 8 | end; 9 | 10 | implementation 11 | 12 | end. 13 | -------------------------------------------------------------------------------- /delphiDatadog.utils.pas: -------------------------------------------------------------------------------- 1 | unit delphiDatadog.utils; 2 | 3 | interface 4 | 5 | uses 6 | delphiDatadog.header; 7 | 8 | function DataTagsToText(Tags: TDataDogTags): string; 9 | 10 | function DataTagsEventPriorityToText(Priority: TDataDogEventPriority): string; 11 | function DataTagsEventAlertToText(AlertType: TDataDogEventAlertType): string; 12 | 13 | function EscapedMessage(Title: string): string; 14 | 15 | implementation 16 | 17 | uses 18 | System.SysUtils; 19 | 20 | function DataTagsToText(Tags: TDataDogTags): string; 21 | var 22 | I: Integer; 23 | Tag: string; 24 | begin 25 | Result := ''; 26 | 27 | if Length(Tags) = 0 then Exit; 28 | 29 | for Tag in Tags do 30 | begin 31 | if Result.IsEmpty then 32 | Result := Tag 33 | else 34 | Result := Result + ',' + Tag 35 | end; 36 | 37 | Result := '|#' + Result; 38 | end; 39 | 40 | function DataTagsEventPriorityToText(Priority: TDataDogEventPriority): string; 41 | begin 42 | case Priority of 43 | ddLow: Result := 'low'; 44 | ddNormal: Result := 'normal'; 45 | end; 46 | end; 47 | 48 | function DataTagsEventAlertToText(AlertType: TDataDogEventAlertType): string; 49 | begin 50 | case AlertType of 51 | ddError: Result := 'error'; 52 | ddWarning: Result := 'warning'; 53 | ddInfo: Result := 'info'; 54 | ddSuccess: Result := 'success'; 55 | ddUndefined: Result := ''; 56 | end; 57 | end; 58 | 59 | function EscapedMessage(Title: string): string; 60 | begin 61 | Result := Title.Replace('\n', '\\n'); 62 | end; 63 | 64 | end. 65 | --------------------------------------------------------------------------------