Skip to content

Client library

remiges-shuvam edited this page Feb 28, 2024 · 28 revisions

LogHarbour provides client libraries, in Java and Go, to allow business applications to perform all operations on a LogHarbour instance. The documentation below specifies the function signatures for the Go version. The semantics are identical in the two versions.

Some of the functions require a master token. A master token is tied to a realm, and is generated by mechanisms outside the client library. See the page on access controls in LogHarbour.

Client management

A client is an abstract entity which acts as a vessel for authorisation capabilities. A business application may create, and then use, any number of clients, and it may associate different capabilities with each client. All function calls to the LogHarbour client library require a client token as a parameter, to identify who is calling the function.

ClientNew()

func LogHarbour.ClientNew(master string, apps []string, caps []string) (client string, err error)

This function will take master, apps and caps as parameters and create a new client record in LogHarbour.

  • master: the token which authenticates the caller to LogHarbour as having the right to perform all user-management operations for a specific realm. The master token carries information to allow LogHarbour to map it to a specific realm.
  • apps: an array of zero or more apps for which this client will be allowed access. Zero means that all access will extend across all apps in the realm.
  • caps: an array of one or more capabilities this client will possess. If these are app-specific capabilities, then they will apply for all the apps listed in apps

The function will connect to the live LogHarbour service, update its data store, generate the client token and return it.

ClientDelete()

func LogHarbour.ClientDelete(client string) (err error)

This function will take a client token and invalidate it. All subsequent attempts to make function calls with this client token will fail. There is no mechanism to revalidate or reactivate a deleted token.

ClientUpdate()

func LogHarbour.ClientUpdate(master, client string, apps []string, caps []string) (err error)

This function will update the apps and capabilities associated with an existing client. This update will not be incremental, it will be analogous to an assignment statement, where the old associations will be completely replaced.

  • master is the master token for a realm
  • client is the client token returned by a previous ClientNew() call
  • apps, caps have the same meanings and same rules as for ClientNew()

App management

An app in LogHarbour is supposed to map onto a business application, or a sub-system of a business application. All log entries are tagged with the apps they belong to, and access to logs for querying is also controlled on a per-app basis.

The master token of your realm must be supplied to call any of these functions.

AppNew()

func LogHarbour.AppNew(master, appshortname, applongname string) (err error)

This function will be used by a business application to add a new app to its realm. The shortname of the app must be unique in the realm.

AppUpdate()

func LogHarbour.AppUpdate(master, applongname string) (err error)

This function will be used by a business application to update the long name of app.

AppDelete()

func LogHarbour.AppDelete(master, app string) (err error)

This function will be used by a business application to delete app by specifying its shortname.

AppList()

func LogHarbour.AppList(client) (apps map[string]string, err error)

This function will be used by a business application to retrieve the list of apps under a realm. The client parameter may carry the master token for a realm, or any client token which has the report capability. The response will carry an associative array of apps, where each key will be a shortname of one app, and the value will be its long name. The function may return a map of zero entries, without any error, if no apps are defined in this realm.

Writing log entries

These functions are needed to write log entries into the various logs of LogHarbour.

WriteActivityLog()

func LogHarbour.WriteActivityLog(client, app string, data any) (err error)

This function will be used by the business application code to write a log entry in the activity log. The client must have writelogs capability for the app for which the entry is being inserted.

WriteDataChgLog()

func LogHarbour.WriteDataChgLog(client, app string, data any) (err error)

This function will be used by the business application code to write a log entry in the data-change log. The client must have writelogs capability for the app for which the entry is being inserted.

WriteDebugLog()

func LogHarbour.WriteDebugLog(client, app string, data any) (err error)

This function will be used by the business application code to write a log entry in the debug log. The client must have writelogs capability for the app for which the entry is being inserted.

Log retrieval

GetLogs()

This function is the general purpose function to fetch log entries from the activity logs and data-change logs in the repository.

type GeneralLog_t struct {
    ts          time.Time            // timestamp of record insertion as maintained by LogHarbour
    docid       string               // unique internally generated record ID
    when        string               // timestamp of event as specified by the business application
    who         string               // some identity information to identify whose action generated this entry
    app         string               // the application ID of the app which generated this entry
    system      string               // the system or server or container where this entry originated
    module      string               // the sub-system of the application where this entry originated
    op          string               // the operation which generated this entry, e.g. "vouchercreate" or "reportget"
    type        string               // "A" for activity log, "C" for data change log, "D" for debug log
    class       string               // the class of object on which this operation was done, e.g. "voucher" or "misreport"
    instance    string               // a unique ID of one object instance of the class specified in "class"
    pri         LogPri_t             // priority of the entry -- an enum
    status      string               // "success", "ok", "err", "failed", "aborted", or some such string
    error       string               // any string which specifies an error which may have occured due to the operation
    remoteIP    string               // the IP address of the system from where the operation was triggered
    message     string               // any string which gives a message to indicate what was done
    data        map[string]string    // a collection of attribute-value pairs of additional info
}
func LogHarbour.GetLogs(client, app, type, who, class, instance string, fromts, tots time.Time, ndays int, remoteIP string, pri LogPri_t,
                                searchAfterTS time.Time, searchAfterDocID string)
                               (logs []GeneralLog_t, nrec int, err error)

where

  • client: mandatory, is the client token of the client which is attempting to retrieve the data
  • app: optional, to extract log entries for just the app specified
  • type: optional, A meaning activity logs, C meaning data-change logs, D meaning debug logs, and omitted meaning all three
  • who: optional, to extract log entries inserted only by actions performed by the specified user
  • class: optional, to extract logs related to objects of the specified class only
  • instance: optional, to extract logs only for a specific object instance. This parameter must be nil if class is not specified.
  • fromts, tots: optional, timestamps, to extract log entries whose when value falls in this time range.
  • ndays: optional, an integer specifying how many days back in time the retrieval must attempt, counting backwards in time from the current date
  • remoteIP: optional, an IP address in string form specifying the remote IP from where the operation was triggered which generated the log entry
  • pri: optional, specifies that only logs of priority equal to or higher than the value given here will be returned
  • searchAfterTS: optional. If specified, it indicates that only logs with timestamps older than the specified parameter must be retrieved
  • searchAfterDocID: optional. If specified, it indicates that only logs whose document IDs are earlier than the one specified must be retrieved.

The three parameters, fromts, tots, and ndays have inter-dependency as follows:

  • If fromts and tots are specified, then tots must be after fromts.
  • If either or both of fromts and tots is specified, then ndays is ignored.
  • If just one of fronts or tots is specified, then the function will return all records which satisfy this filter, up to a maximum of LOGHARBOUR_GETLOGS_MAXREC entries, where the value of this parameter is a global configuration entry. If fromts is specified, then entries will be returned sorted forward in time (i.e. oldest to newest) based on the when field. If tots is specified then entries will be sorted from newest to oldest.

Under all circumstances, the response carries an array of up to LOGHARBOUR_GETLOGS_MAXREC entries. Each entry has fields as mentioned in the annotated data structure definition above.

The client token specified must have activitylogs capability if activity logs are to be included in the response, datachglogs capability if data-change logs are to be included, and debuglogs capability if debug logs are to be included.

Data-change logs have no priority. If pri is specified, the function excludes data-change logs from its result set.

The searchAfterTS and searchAfterDocID parameters must have the value nil the first time this function is called with a specific set of parameters. This call returns at most LOGHARBOUR_GETLOGS_MAXREC entries. The actual number of entries matching this request is returned in nrecs. If this number exceeds the value of LOGHARBOUR_GETLOGS_MAXREC, then the function is called again with exactly the same set of parameters but with specific values for these two parameters, which makes the function skip the earlier block(s) of entries and fetch only the next set. This way, the same function can retrieve a large data set over multiple calls, getting LOGHARBOUR_GETLOGS_MAXREC entries in every call.

GetUnusualIP()

This function will go through the logs of the last ndays days which match the search criteria, and pull out all the remote IP addresses which account for a low enough percentage of the total to be treated as unusual or suspicious.

func LogHarbour.GetUnusualIP(client, app, who, class, op string, ndays int, unusualpercent float32) (unusualIPs []string, err error)

where

  • client is the client token which authorises the call to the function
  • app: optional, the application ID whose matching log entries must be searched
  • who: optional, the user identity whose log entries must be searched
  • class: optional, the class of entities whose log entries must be searched
  • op: optional, the operation which triggered the generation of the log entries which must be searched. This parameter may carry a meaningful value only if class has been specified, and will be ignored if class is nil.
  • ndays: optional, an integer specifying how many days back in time the retrieval must attempt, counting backwards in time from the current date. If this is omitted, then the most recent LOGHARBOUR_GETLOG_MAXREC log entries will be processed
  • unusualpercent: mandatory, specifies the percent upper limit of an IP address' occurrence in the list of remote IPs for it to be considered "unusual". Typical values will range between 0.5 and 5.0. A value above 50 will be rejected and the function will return with an error.

The processing will require that the client have activitylogs, datachglogs or report capabilities

function GetUnusualIP(filtering parameters, ndays, unusualpercent):
  # Aggregate logs by IP and count occurrences
  aggregatedIPs = select remoteIPs of log entries matching the request parameters
  
  # Calculate total number of logs to find what 1% represents
  var PercentThreshold float = count_of(aggregatedIPs) * unusualpercent / 100.0
  if PercentThreshold < 1, then PercentThreshold = 1, endif

  # Initialize an empty list to hold unusual IPs
  unusualIPs = []

  # For each IP in the aggregated IP list
  for each IP in aggregatedIPs do
      # If the count of logs for this IP is less than the threshold
      if IP.count <= onePercentThreshold, then
          if IP.address != "LOCAL" then
              unusualIPs.append(IP.address)
          endif
      endif
  done

  return unusualIPs

The response will return a list of "unusual" IP addresses from all the matching log entries.

Clone this wiki locally