Lizenznutzungsberichte
Lizenznutzungsberichte zeigen im Einzelnen, wie Ihre Anwendung lizenzierte Funktionen, Felder und Einschränkungen verwendet. Wenn Sie die Erfassung der Lizenznutzung einschalten, können Sie die Akzeptanz von Funktionen beobachten, die Konformität prüfen und datengestützte Entscheidungen über Ihre Lizenzierungsstrategie treffen.
Übersicht
Die Bibliothek von Babel Licensing enthält ein leistungsfähiges Erfassungssystem, das die Zugriffe auf Lizenzkomponenten automatisch überwacht:
- Nutzung von Funktionen: erfassen, auf welche Funktionen zugegriffen wird, wie oft und über welche Member
- Zugriff auf Felder: überwachen, welche Lizenzfelder gelesen werden und welche Werte sie haben
- Validierung von Einschränkungen: Prüfungen von Einschränkungen und ihre Validierungsergebnisse aufzeichnen
- Automatische Sammlung: Nutzungsdaten werden transparent und ohne Codeänderungen erfasst
- Intelligente Zusammenführung: Der Server fasst Berichte für eine umfassende Analyse zusammen
Beispiel einer Konsolenanwendung
Für den Einstieg mit einem praktischen Beispiel klonen Sie das Repository console-licensing-report-example. Es zeigt, wie Sie mit den Reporting-Funktionen von Babel die Lizenznutzung erfassen und Lizenznutzungsberichte senden.
Git-Client öffnen
Öffnen Sie Ihren bevorzugten Git-Client oder die Befehlszeile.
Repository klonen
Klonen Sie das GitHub-Repository mit dem folgenden Befehl:
git clone https://github.com/babelfornet/console-licensing-report-example.gitIn das Projektverzeichnis wechseln
Wechseln Sie nach dem Klonen des Repositorys in das Projektverzeichnis:
cd console-licensing-report-exampleBeispiel erkunden und ausführen
Jetzt können Sie den Beispielcode erkunden und ausführen.
Das Beispiel console-licensing-report-example zeigt, wie Sie die Clientbibliothek von Babel Licensing in Ihre Anwendung integrieren, um die Lizenznutzung zu erfassen und Lizenznutzungsberichte an den Babel Licensing Service zu senden. Der Code im Einzelnen:
- Initialisierung von BabelReporting und BabelLicensing: Der Beispielcode initialisiert ein
BabelReporting-Objekt zum Senden von Berichten und einBabelLicensing-Objekt für die Lizenzvalidierung.
private BabelReporting CreateReportingClient()
{
var reporting = new BabelReporting();
reporting.Configuration.ClientId = ClientId;
reporting.Configuration.ServiceUrl = ServiceUrl;
reporting.Configuration.UseHttp(http => {
http.Timeout = TimeSpan.FromSeconds(3);
http.Handler = new HttpClientHandler() {
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
};
});
reporting.BeforeSendReport += (s, e) => {
e.Report.Properties.Add("cmdline", Environment.CommandLine);
e.Report.Properties.Add("username", Environment.UserName);
};
return reporting;
}
private BabelLicensing CreateLicensingClient()
{
var config = new BabelLicensingConfiguration()
{
ServiceUrl = ServiceUrl,
SignatureProvider = RSASignature.FromKeys(PublicKey),
ClientId = ClientId
};
config.UseHttp(http => {
http.Timeout = TimeSpan.FromSeconds(10);
http.Handler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
};
});
// Register custom license factory to handle MemoryRestriction
config.LicenseFactory = new CustomLicenseFactory();
return new BabelLicensing(config);
}-
Benutzerschlüssel und öffentlicher Schlüssel: Der Beispielcode verwendet einen Benutzerschlüssel (
UserKey), um den Client zu autorisieren, und einen öffentlichen Schlüssel (PublicKey), um die Signatur der Lizenz zu prüfen. Ersetzen Sie beide durch gültige Schlüssel. Wie Sie einen Benutzerschlüssel erzeugen, lesen Sie in den Abschnitten Floating-Lizenz oder Lizenzaktivierung. -
Lizenzvalidierung mit Erfassung: Das Beispiel zeigt, wie Sie eine Floating-Lizenz validieren und auf ihre Funktionen, Felder und Einschränkungen zugreifen. Alle Zugriffe werden automatisch erfasst, wenn
LicenseUsageTrackingeingeschaltet ist:
private async Task ValidateLicenseAsync()
{
try
{
// Acquire floating license
var requestResult = await _licensing.RequestFloatingLicenseAsync(UserKey, typeof(Program));
Console.WriteLine($"Floating license {requestResult.License.Id} acquired.");
try
{
// Validate the license (this will be tracked)
var result = await _licensing.ValidateLicenseAsync(UserKey, typeof(Program));
var license = result.License;
Console.WriteLine($"License validated: {license.Id}");
foreach (var feature in license.Features)
{
Console.WriteLine($" Feature: {feature.Name} - {feature.Description}");
}
foreach (var field in license.Fields)
{
Console.WriteLine($" Field: {field.Name} = {field.Value}");
}
foreach (var restriction in license.Restrictions)
{
Console.WriteLine($" Restriction: {restriction.Name}");
}
// Simulate multiple accesses to demonstrate tracking
var reportingFeature = license.Features.FirstOrDefault(f => f.Name == "Reporting");
var field2Field = license.Fields.FirstOrDefault(f => f.Name == "field2");
for (int i = 0; i < 5; i++)
{
var _ = reportingFeature?.Data;
var __ = field2Field?.Value;
}
Console.WriteLine($"\nLicense validation completed.");
}
finally
{
// Always release the floating license when done
await _licensing.ReleaseFloatingLicenseAsync(UserKey);
Console.WriteLine("Floating license released.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error validating license: {ex.Message}");
}
}- Senden des Lizenznutzungsberichts: Die Methode
SendLicenseReportAsyncsendet die gesammelten Erfassungsdaten an den Babel Licensing Service:
private async Task SendLicenseReportAsync()
{
var result = await _reporting.SendLicenseReportAsync(UserKey);
if (result.IsError)
{
Console.WriteLine($"Error sending LicenseReport: {result.Error}");
return;
}
Console.WriteLine("LicenseReport sent.");
}- Benutzerdefinierte Lizenz-Factory: Das Beispiel enthält eine benutzerdefinierte Klasse
MemoryRestrictionund eineCustomLicenseFactory. Beide zeigen, wie Sie benutzerdefinierte Einschränkungstypen in Ihren Lizenzen behandeln:
class MemoryRestriction : Restriction, ILicenseSerializable
{
public override string Name => "Memory";
public long TotalMemory { get; set; }
public override ValidationResult Validate(ILicenseContext context, Type type, object instance)
{
ISystemInformation sys = (ISystemInformation)context.GetService(typeof(ISystemInformation));
long totalMem = ToMegabytes(sys.TotalPhysicalMemory);
if (totalMem < TotalMemory)
return ValidationResult.Invalid;
return base.Validate(context, type, instance);
}
private static long ToMegabytes(long bytes)
{
return bytes / 1024 / 1024;
}
// ILicenseSerializable implementation...
}
class CustomLicenseFactory : ILicenseFactory
{
public Restriction CreateRestriction(string type)
{
string[] tokens = type.Split(':');
string restriction = tokens[0];
switch (restriction)
{
case "Memory":
var memory = new MemoryRestriction();
if (tokens.Length > 1)
memory.TotalMemory = long.Parse(tokens[1]);
return memory;
default:
return null!;
}
}
// Other ILicenseFactory methods...
}
Beispiel eines Lizenznutzungsberichts
Das Beispiel console-licensing-report-example zeigt in der Praxis, wie Sie die Lizenznutzung erfassen und Berichte an den Babel Licensing Service senden. Wenn Sie die Erfassung der Lizenznutzung in Ihre Anwendungen integrieren, können Sie die Akzeptanz von Funktionen beobachten, die Konformität prüfen und datengestützte Entscheidungen über Ihre Lizenzierungsstrategie treffen.
Erfassung der Lizenznutzung einschalten
Um die Lizenznutzung zu erfassen, schalten Sie die Erfassung ein, bevor Sie Ihre Lizenz validieren:
using Babel.Licensing.Reports;
// Enable tracking (must be called before license validation)
LicenseUsageTracking.Enable();
// Validate your license as usual
var license = licenseManager.Validate(key, type);
// Use licensed features - access is automatically tracked
var reportingFeature = license.Features["Reporting"];
var data = reportingFeature.Data;
var versionField = license.Fields["Version"];
var version = versionField.Value;Lizenznutzungsberichte senden
Sobald die Erfassung eingeschaltet ist, können Sie Berichte an Ihren Babel Licensing Service senden:
using Babel.Licensing.Services;
// Initialize the reporting service
var reporting = new BabelReporting();
reporting.Configuration.ServiceUrl = "https://licensing.example.com";
reporting.Configuration.ClientId = "MyApplication";
// Send the license report
var result = await reporting.SendLicenseReportAsync(userKey);
if (result.Success)
{
Console.WriteLine($"Report sent successfully: {result.ReportUid}");
}
else
{
Console.WriteLine($"Failed to send report: {result.Error?.Message}");
}Was erfasst wird
Erfassung der Zugriffe auf Funktionen
Für jede Funktion Ihrer Lizenz, auf die zugegriffen wird:
// This access is automatically tracked
var feature = license.Features["Reporting"];
var data = feature.Data; // Tracked: get_Data on Reporting featureErfasste Informationen:
- Name und ID der Funktion
- Member, auf den zugegriffen wurde (zum Beispiel
get_Data,get_IsEnabled) - Anzahl der Zugriffe
- Zeitstempel des ersten Zugriffs
- Zeitstempel des letzten Zugriffs
- Gesamtdauer der Zugriffe (Zeit zwischen dem ersten und dem letzten Zugriff)
Erfassung der Zugriffe auf Felder
Für jedes Feld, das aus Ihrer Lizenz gelesen wird:
// This access is automatically tracked
var field = license.Fields["Version"];
var value = field.Value; // Tracked: get_Value on Version fieldErfasste Informationen:
- Name des Felds
- Wert des Felds (aus Datenschutzgründen auf 12 Zeichen gekürzt)
- Member, auf den zugegriffen wurde (zum Beispiel
get_Value) - Anzahl und Zeitstempel der Zugriffe
Erfassung der Validierung von Einschränkungen
Für jede geprüfte Einschränkung:
// This validation is automatically tracked
var validation = license.Restrictions.Validate();Erfasste Informationen:
- Name und Typ der Einschränkung
- Validierungsergebnis (Pass/Fail)
- Member, auf den zugegriffen wurde
- Anzahl und Zeitstempel der Zugriffe
Inhalt des Berichts
Jeder Lizenznutzungsbericht umfasst drei Hauptabschnitte:
1. Metadaten der Lizenz
Grundlegende Informationen über die erfasste Lizenz:
{
"license_id": "L-ABC-123",
"license_type": "Standard",
"issue_date": "2025-01-15",
"expire_date": "2026-01-15",
"support_expire_date": "2025-07-15",
"licensee_name": "John Smith",
"licensee_company": "ACME Corporation",
"product_name": "EquiTrack",
"product_version": "2.0"
}2. Daten der Nutzungserfassung
Ausführliche Zugriffsstatistiken für alle erfassten Komponenten:
{
"features": [
{
"id": "F-001",
"name": "Reporting",
"members": [
{
"member": "get_Data",
"access_count": 15,
"first_access": "2025-01-20T10:30:00Z",
"last_access": "2025-01-20T14:45:00Z",
"access_time": "04:15:00"
}
]
}
],
"fields": [
{
"name": "Version",
"value": "2.0.1",
"members": [
{
"member": "get_Value",
"access_count": 3,
"first_access": "2025-01-20T10:00:00Z"
}
]
}
],
"restrictions": [
{
"name": "MachineLock",
"type": "Hardware",
"members": [
{
"member": "Validate",
"access_count": 1,
"validation_result": "Pass",
"first_access": "2025-01-20T10:00:00Z"
}
]
}
]
}3. Umgebungs- und Systeminformationen
Kontext zur Anwendung und zum Rechner (konfigurierbar):
- Name und Version der Anwendung sowie die geladenen Assemblys
- Details zum Betriebssystem
- Hardwareinformationen (CPU, Arbeitsspeicher, Datenträger)
- Netzwerkadapter
- Umgebungsvariablen (gefiltert)
- Laufende Prozesse (optional)
Konfigurationsoptionen
Legen Sie fest, welche Daten in Ihre Lizenznutzungsberichte aufgenommen werden:
var reporting = new BabelReporting();
// Configure license report options
reporting.Configuration.LicenseReportOptions = new LicenseReportOptions
{
// What to track
CollectFeaturesAccess = true,
CollectFieldsAccess = true,
CollectRestrictionsAccess = true,
// Filter specific members (optional)
CollectMembers = new List<string> { "get_Data", "get_IsEnabled" },
// Environment information
Environment = new EnvironmentReportOptions
{
CollectApplicationInformation = true,
CollectLoadedAssemblies = true,
CollectEnvironmentVariables = false,
CollectProcessInformation = false
},
// System information
System = new SystemReportOptions
{
CollectSystemInformation = true,
CollectOsInformation = true,
CollectProcessorInformation = true,
CollectMemoryInformation = true,
CollectDiskInformation = false,
CollectDisplayInformation = false,
CollectNetworkInformation = false
},
// Output options
Formatted = true, // Pretty-print JSON
EncryptionKey = "my-secret-key" // Optional encryption
};Erfasste Daten verwalten
Erfassungsstatus prüfen
if (LicenseUsageTracking.IsEnabled)
{
Console.WriteLine("License tracking is active");
}Auf erfasste Informationen zugreifen
// Get all tracked licenses
foreach (var info in LicenseUsageTracking.TrackedLicenses)
{
Console.WriteLine($"License: {info.LicenseId}");
Console.WriteLine($"Product: {info.ProductName} v{info.ProductVersion}");
// Feature access details
foreach (var feature in info.TrackedFeatures)
{
Console.WriteLine($" Feature {feature.Name}:");
Console.WriteLine($" Accesses: {feature.AccessCount}");
Console.WriteLine($" First: {feature.FirstAccessTime}");
Console.WriteLine($" Last: {feature.LastAccessTime}");
}
// Field access details
foreach (var field in info.TrackedFields)
{
Console.WriteLine($" Field {field.Name}: {field.AccessCount} accesses");
}
// Restriction validation details
foreach (var restriction in info.TrackedRestrictions)
{
Console.WriteLine($" Restriction {restriction.Name}: {restriction.AccessCount} checks");
}
}Erfassung einer bestimmten Lizenz abrufen
var trackingInfo = LicenseUsageTracking.GetTrackingInfo("L-ABC-123");
if (trackingInfo != null)
{
Console.WriteLine($"Tracking {trackingInfo.TrackedFeatures.Count()} features");
}Erfassungsdaten löschen
// Clear all tracked data without disabling tracking
LicenseUsageTracking.Clear();Erfassung ausschalten
// Disable tracking and clear all data
LicenseUsageTracking.Disable();Berichte anpassen
Fügen Sie Ihren Lizenznutzungsberichten über das Ereignis BeforeSendReport benutzerdefinierte Eigenschaften hinzu:
reporting.BeforeSendReport += (s, e) =>
{
// Add custom metadata
e.Report.Properties.Add("application_mode", "production");
e.Report.Properties.Add("user_count", activeUsers);
e.Report.Properties.Add("deployment_id", deploymentId);
// Cancel sending if needed
if (shouldSkipReport)
{
e.Cancel = true;
}
};Zusammenführung von Berichten
Der Babel Licensing Service führt Lizenznutzungsberichte desselben Clients und desselben Rechners automatisch zusammen. Daraus ergeben sich:
- Kumulierte Statistiken: Die Zugriffszahlen werden addiert
- Erhalt der Zeitachse: Der früheste erste Zugriff und der späteste letzte Zugriff bleiben erhalten
- Historische Analyse: vollständige Nutzungsmuster im Zeitverlauf
- Effiziente Speicherung: ein einziger umfassender Bericht je Lizenz, Rechner und Client
Wenn ein neuer Bericht eintrifft, geht der Server so vor:
- Er ermittelt die vorhandenen Berichte mit derselben Lizenz-ID, Rechner-ID und Client-ID
- Er führt die Erfassungsdaten nach Komponentenname und Member zusammen
- Er summiert die Zugriffszahlen
- Er aktualisiert die Zeitspannen der Zugriffe
- Er aktualisiert die Metadaten mit den neuesten Werten
Fehlerbehandlung
Fangen Sie Fehler beim Senden von Berichten sauber ab:
reporting.AfterSendReport += (s, e) =>
{
if (e.Error != null)
{
// Log the error
logger.LogError(e.Error, "Failed to send license report");
// Store report locally for retry
SaveReportForRetry(e.Report);
}
else
{
logger.LogInformation($"Report sent: {e.Result.ReportUid}");
}
};
var result = await reporting.SendLicenseReportAsync(userKey);Bewährte Vorgehensweisen
1. Früh einschalten
Schalten Sie die Erfassung ein, bevor Sie Ihre Lizenz validieren, damit alle Zugriffe von Anfang an erfasst werden:
// GOOD: Enable before validation
LicenseUsageTracking.Enable();
var license = licenseManager.Validate(key, type);
// BAD: Enable after validation (misses initial access)
var license = licenseManager.Validate(key, type);
LicenseUsageTracking.Enable();2. Regelmäßig senden
Senden Sie Berichte in regelmäßigen Abständen oder beim Beenden der Anwendung:
// Option 1: Periodic reporting
var timer = new Timer(async _ =>
{
if (LicenseUsageTracking.IsEnabled)
{
await reporting.SendLicenseReportAsync(userKey);
LicenseUsageTracking.Clear(); // Reset for next period
}
}, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1));
// Option 2: On application shutdown
AppDomain.CurrentDomain.ProcessExit += async (s, e) =>
{
await reporting.SendLicenseReportAsync(userKey);
};3. Datensammlung minimieren
Sammeln Sie nur die Daten, die Sie benötigen, um die Größe der Berichte und die Netzwerklast zu verringern:
reporting.Configuration.LicenseReportOptions = new LicenseReportOptions
{
CollectFeaturesAccess = true, // Essential
CollectFieldsAccess = false, // Skip if not needed
CollectRestrictionsAccess = true, // For compliance
System = new SystemReportOptions
{
CollectSystemInformation = true,
CollectDiskInformation = false, // Skip to reduce size
CollectDisplayInformation = false
}
};4. Offline-Szenarien berücksichtigen
Speichern Sie Berichte lokal, wenn der Server nicht erreichbar ist:
var result = await reporting.SendLicenseReportAsync(userKey);
if (!result.Success)
{
// Serialize and store report
var reportJson = JsonSerializer.Serialize(result.Report);
await File.WriteAllTextAsync("pending-reports/report-" + Guid.NewGuid() + ".json", reportJson);
}5. Sensible Daten schützen
Verschlüsseln Sie Berichte, die sensible Informationen enthalten:
reporting.Configuration.EncryptionKey = Configuration["Reporting:EncryptionKey"];
reporting.Configuration.LicenseReportOptions.EncryptionKey = reporting.Configuration.EncryptionKey;Beispiel: vollständige Erfassung der Lizenznutzung
Das folgende umfassende Beispiel zeigt die Erfassung der Lizenznutzung in einer realen Anwendung:
using Babel.Licensing;
using Babel.Licensing.Reports;
using Babel.Licensing.Services;
public class LicenseManager
{
private readonly BabelReporting _reporting;
private readonly Timer _reportTimer;
public LicenseManager(IConfiguration configuration)
{
// Initialize reporting service
_reporting = new BabelReporting();
_reporting.Configuration.ServiceUrl = configuration["Licensing:ServiceUrl"];
_reporting.Configuration.ClientId = "EquiTrack v2.0";
_reporting.Configuration.EncryptionKey = configuration["Licensing:EncryptionKey"];
// Configure what to track
_reporting.Configuration.LicenseReportOptions = new LicenseReportOptions
{
CollectFeaturesAccess = true,
CollectFieldsAccess = true,
CollectRestrictionsAccess = true,
Environment = new EnvironmentReportOptions
{
CollectApplicationInformation = true,
CollectLoadedAssemblies = true
},
System = new SystemReportOptions
{
CollectSystemInformation = true,
CollectOsInformation = true,
CollectProcessorInformation = true,
CollectMemoryInformation = true
},
Formatted = false // Compact JSON for network efficiency
};
// Add custom properties before sending
_reporting.BeforeSendReport += (s, e) =>
{
e.Report.Properties.Add("environment", configuration["Environment"]);
e.Report.Properties.Add("version", Assembly.GetExecutingAssembly().GetName().Version.ToString());
};
// Handle send results
_reporting.AfterSendReport += (s, e) =>
{
if (e.Error != null)
{
Logger.Error($"Failed to send license report: {e.Error.Message}");
}
else
{
Logger.Info($"License report sent: {e.Result.ReportUid}");
}
};
// Send reports every 24 hours
_reportTimer = new Timer(
async _ => await SendLicenseReportAsync(),
null,
TimeSpan.FromHours(24),
TimeSpan.FromHours(24)
);
}
public ILicense ValidateLicense(string userKey, LicenseKeyTypes keyType)
{
// Enable tracking before validation
LicenseUsageTracking.Enable();
// Validate license
var licenseManager = new BabelLicensing();
var license = licenseManager.Validate(userKey, keyType);
return license;
}
public async Task SendLicenseReportAsync()
{
if (!LicenseUsageTracking.IsEnabled)
return;
try
{
var result = await _reporting.SendLicenseReportAsync(_userKey);
if (result.Success)
{
// Clear tracking data after successful send
LicenseUsageTracking.Clear();
}
}
catch (Exception ex)
{
Logger.Error($"Exception sending license report: {ex.Message}");
}
}
public void Shutdown()
{
// Send final report on shutdown
SendLicenseReportAsync().Wait(TimeSpan.FromSeconds(10));
// Cleanup
_reportTimer?.Dispose();
LicenseUsageTracking.Disable();
}
}Serverseitige Analyse
Sobald die Berichte bei Ihrem Babel Licensing Service eingegangen sind, können Sie:
- Akzeptanz von Funktionen beobachten: sehen, welche Funktionen am häufigsten verwendet werden
- Ungenutzte Funktionen erkennen: Funktionen finden, auf die nie zugegriffen wird
- Nutzungsmuster verfolgen: Zeitpunkte und Häufigkeit der Zugriffe auswerten
- Konformität prüfen: sicherstellen, dass Einschränkungen geprüft werden
- Lizenzierungsstrategie planen: datengestützte Entscheidungen über die Bündelung von Funktionen treffen
Berichte werden mit allen Metadaten gespeichert. Sie können sie über die API des Babel Licensing Service abfragen oder in der Verwaltungsoberfläche ansehen.
Verwandte Themen
- Fehlerberichte: Absturz- und Fehlerberichte senden
- Benutzerdefinierte Berichte: eigene Berichtstypen erstellen
- Floating-Lizenz: Benutzerschlüssel für das Reporting erzeugen
- Lizenzaktivierung: Lizenzen für die Erfassung aktivieren