Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
15fd42b
feat(WindowsMetrics.fs): Added Processor Metrics
MathusanP Jul 25, 2026
73c11c1
feat(WindowsMetrics.fs): Added disk information
MathusanP Jul 26, 2026
72eb47b
feat(WindowsMetrics.fs): Added metrics for graphical processors
MathusanP Jul 29, 2026
995ebfc
fea(DeviceMetrics.fs): Added uptime metric
MathusanP Aug 9, 2026
dd1a6e5
feat(tests): Added unit tests and pipeline runs for tests
MathusanP Aug 9, 2026
7f99dab
fix(tests.yml): Switched build os to windows
MathusanP Aug 9, 2026
045d09e
feat(NetworkMetrics.fs): Added network metrics
MathusanP Aug 10, 2026
6c5add7
chore(test.yml): Changed dotnet version to 9.0.x
MathusanP Aug 10, 2026
0395ac3
feat(DeviceMetrics.fs): Added architecture information and error hand…
MathusanP Aug 10, 2026
faddb71
Merge branch 'feature/metrics-endpoint' of https://github.com/Mathusa…
MathusanP Aug 10, 2026
1998e0a
feat: Made Http endpoints
MathusanP Aug 22, 2026
87644a0
fix(Pryde.Api/Handlers.fs): Changed content handler to explicit
MathusanP Aug 23, 2026
c355b9e
Merge branch 'master' into feature/metrics-endpoint
MathusanP Aug 23, 2026
9654833
chore(tests.fs): changed type(args) to new type(args)
MathusanP Sep 3, 2026
8e47db1
Merge branch 'feature/metrics-endpoint' of https://github.com/Mathusa…
MathusanP Sep 3, 2026
25f007a
chore(NetworkMetrics.fs): Changed network metrics from let to use Sea…
MathusanP Sep 3, 2026
392a2e1
refactor(Handlers.fs): Improved status code handling
MathusanP Sep 4, 2026
46283dd
feat(RouteTests.fs): Added routes testing
MathusanP Sep 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/Pryde.Api/Handlers.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module Pryde.Api.Handlers

open Giraffe
open Pryde.Data

let getCpuHandler : HttpHandler =
fun next ctx ->
json (DeviceMetrics.getCpuInfo ()) next ctx

let getDiskHandler : HttpHandler =
fun next ctx ->
json (DeviceMetrics.getDiskInfo ()) next ctx

let getGraphicsHandler : HttpHandler =
fun next ctx ->
json (DeviceMetrics.getGraphicsInfo ()) next ctx

let getUptimeHandler : HttpHandler =
fun next ctx ->
json (DeviceMetrics.getUptime ()) next ctx

let getNetworkThroughputHandler : HttpHandler =
fun next ctx ->
json (NetworkMetrics.getNetworkThroughput ()) next ctx
Comment thread
MathusanP marked this conversation as resolved.

let getPortHandler (port: int) : HttpHandler =
fun next ctx ->
if port < 1 || port > 65535 then
(setStatusCode 400 >=> json {| message = "Invalid port number" |}) next ctx
else
match NetworkMetrics.getPortInfo port with
| Some info -> json info next ctx
| None -> (setStatusCode 404 >=> json {| message = "Port not listening" |}) next ctx
38 changes: 18 additions & 20 deletions src/Pryde.Api/Program.fs
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
open System
namespace Pryde.Api

open Giraffe
open Pryde.Api.Routes
open Microsoft.AspNetCore.Builder
open Microsoft.Extensions.Hosting
open Pryde.Data
open Pryde.Data.NetworkMetrics
open Microsoft.Extensions.DependencyInjection

[<EntryPoint>]
let main args =
let cpu = DeviceMetrics.getCpuInfo ()
let disk = DeviceMetrics.getDiskInfo ()
let gpu = DeviceMetrics.getGraphicsInfo()
let networkThroughput = NetworkMetrics.getNetworkThroughput()

printfn "%A" cpu
printfn "%A" disk
printfn "%A" gpu
printfn "%A" networkThroughput

let builder = WebApplication.CreateBuilder(args)
let app = builder.Build()

app.Run()
type Program() =
class end

0 // Exit code
module Program =
[<EntryPoint>]
let main args =
let builder = WebApplication.CreateBuilder(args)
builder.Services.AddGiraffe() |> ignore

let app = builder.Build()
app.UseGiraffe(webApp)

app.Run()
0 // Exit code
4 changes: 4 additions & 0 deletions src/Pryde.Api/Pryde.Api.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="Handlers.fs" />
<Compile Include="Routes.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Pryde.Core\Pryde.Core.fsproj" />
<ProjectReference Include="..\Pryde.Polling\Pryde.Polling.fsproj" />
<ProjectReference Include="..\Pryde.Data\Pryde.Data.fsproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Giraffe" Version="8.3.0" />
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.7-pre714" />
</ItemGroup>

Expand Down
15 changes: 15 additions & 0 deletions src/Pryde.Api/Routes.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Pryde.Api.Routes

open Giraffe
open Pryde.Api.Handlers
let webApp : HttpHandler =
choose [
GET >=> choose [
route "/system/cpu" >=> getCpuHandler
route "/system/disk" >=> getDiskHandler
Comment thread
MathusanP marked this conversation as resolved.
route "/system/graphics" >=> getGraphicsHandler
route "/system/uptime" >=> getUptimeHandler
route "/network/throughput" >=> getNetworkThroughputHandler
routef "/network/port/%i" getPortHandler
]
]
2 changes: 1 addition & 1 deletion src/Pryde.Data/NetworkMetrics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module NetworkMetrics =
let getNetworkThroughput () : NetworkInfo list =
use searcher = new ManagementObjectSearcher(
"SELECT Name, BytesReceivedPersec, BytesSentPersec FROM Win32_PerfFormattedData_Tcpip_NetworkInterface")
let results = searcher.Get()
use results = searcher.Get()

[ for item in results do
let name = item.["Name"] :?> string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ module NetworkMetricsTest =
[<Fact>]
let ``isPortListening returns true for a port with an active listener`` () =
let testPort = 54321
let listener = TcpListener(IPAddress.Loopback, testPort)
let listener = new TcpListener(IPAddress.Loopback, testPort)
listener.Start()

try
Expand Down
5 changes: 4 additions & 1 deletion tests/Pryde.Tests/Pryde.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="Tests.fs" />
<Compile Include="MetricTests.fs" />
<Compile Include="RouteTests.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.*" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Pryde.Data\Pryde.Data.fsproj" />
<ProjectReference Include="..\..\src\Pryde.Api\Pryde.Api.fsproj" />
</ItemGroup>

</Project>
37 changes: 37 additions & 0 deletions tests/Pryde.Tests/RouteTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module Pryde.Tests

open Microsoft.AspNetCore.Mvc.Testing
open Xunit
open System.Net
open Pryde.Api

type RouteTests() =
let factory = new WebApplicationFactory<Program>()
let client = factory.CreateClient()

[<Fact>]
member _.``GET system cpu returns 200`` () = task {
let! response = client.GetAsync("/system/cpu")
Assert.Equal(HttpStatusCode.OK, response.StatusCode)
}

[<Fact>]
member _. ``GET system disk returns 200`` () = task {
let! response = client.GetAsync("/system/disk")
Assert.Equal(HttpStatusCode.OK, response.StatusCode)
}

[<Fact>]
member _.``Get network port with invalid port returns 400`` () = task {
let! response = client.GetAsync("/network/port/-1")
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode)
}

[<Fact>]
member _.``Get network port with unused port returns 404`` () = task {
let! response = client.GetAsync("/network/port/59999")
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode)
}

interface System.IDisposable with
member _.Dispose() = factory.Dispose()
Loading