text:
package com.devicehive.service;

import com.devicehive.dao.CacheConfig;
import com.devicehive.dao.GenericDAO;
import com.devicehive.model.Device;
import com.devicehive.model.DeviceClass;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Optional;

@Component
@Lazy(false)
public class DeviceActivityService {
    private static final Logger logger = LoggerFactory.getLogger(DeviceActivityService.class);

    private static final String DEVICE_ACTIVITY_MAP = "DEVICE-ACTIVITY";

    @Autowired
    private GenericDAO genericDAO;

    @Autowired
    private HazelcastInstance hzInstance;

    private IMap<String, Long> deviceActivityMap;

    @PostConstruct
    public void postConstruct() {
        deviceActivityMap = hzInstance.getMap(DEVICE_ACTIVITY_MAP);
    }

    public void update(String deviceGuid) {
        deviceActivityMap.put(deviceGuid, System.currentTimeMillis());
    }

    @Scheduled(cron = "0 */5 * * * *")//(hour = "*", minute = "*/5", persistent = false)
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void processOfflineDevices() {
        logger.debug("Checking lost offline devices");
        long now = System.currentTimeMillis();
        for (final String deviceGuid : deviceActivityMap.keySet()) {
            Device device = genericDAO.createNamedQuery(Device.class, "Device.findByUUID", Optional.of(CacheConfig.refresh()))
                    .setParameter("guid", deviceGuid)
                    .getResultList()
                    .stream().findFirst().orElse(null);
            if (device == null) {
                logger.warn("Device with guid {} does not exists", deviceGuid);
                deviceActivityMap.remove(deviceGuid);
            } else {
                logger.debug("Checking device {} ", device.getGuid());
                DeviceClass deviceClass = device.getDeviceClass();
                if (deviceClass.getOfflineTimeout() != null) {
                    Long time = deviceActivityMap.get(deviceGuid);
                    if (now - time > deviceClass.getOfflineTimeout() * 1000) {
                        if (deviceActivityMap.remove(deviceGuid, time)) {
                            Device device1 = genericDAO.createNamedQuery(Device.class, "Device.findByUUID", Optional.of(CacheConfig.refresh()))
                                    .setParameter("guid", deviceGuid)
                                    .getResultList()
                                    .stream().findFirst().orElse(null);
                            device1.setStatus("Offline");
                            logger.warn("Device {} is now offline", device1.getGuid());
                        }
                    }
                }
            }
        }
        logger.debug("Checking lost offline devices complete");
    }

}


text:
using GFMatch3.GameCore;
using GFMatch3.GameTools;

namespace GFMatch3.GameImpl {
    /// <summary>
    /// Простой конечный автомат для состояния доски на основе добавлени/удаления GameAction'ов из объекта доски.
    /// Пробуем активировать совпадения. Если совпадения были, то переход в BoardStateActionCondense,
    /// если нет, то в BoardStateActionPlayer.
    /// Переход в состояния: BoardStateActionCondense или BoardStateActionPlayer.
    /// </summary>
    public class BoardStateActionActivateMatches : GameAction {
        public override void OnUpdate() {
            if (AnimationsManager.Instance.HasActiveBlockeableAnimations()) return;

            if (((GOBoard) GameObject).ActivateMatches(false)) {
                GameObject.AddAction(new BoardStateActionCondense());
            } else {
                GameObject.AddAction(new BoardStateActionPlayer());
            }
            RemoveFromParent();
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Permissions;

namespace Charlotte
{
	public partial class StartServerDlg : Form
	{
		#region ALT_F4 抑止

		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
		protected override void WndProc(ref Message m)
		{
			const int WM_SYSCOMMAND = 0x112;
			const long SC_CLOSE = 0xF060L;

			if (m.Msg == WM_SYSCOMMAND && (m.WParam.ToInt64() & 0xFFF0L) == SC_CLOSE)
				return;

			base.WndProc(ref m);
		}

		#endregion

		public StartServerDlg()
		{
			InitializeComponent();
		}

		private void StartServerDlg_Load(object sender, EventArgs e)
		{
			// noop
		}

		private void StartServerDlg_Shown(object sender, EventArgs e)
		{
			this.MainTimer.Enabled = true;
		}

		private void StartServerDlg_FormClosed(object sender, FormClosedEventArgs e)
		{
			this.MainTimer.Enabled = false;
		}

		private long MT_Count;

		private void MainTimer_Tick(object sender, EventArgs e)
		{
			try
			{
				if (20 <= this.MT_Count) // 2 sec <=
				{
					Gnd.I.StartServer();

					this.MainTimer.Enabled = false;
					this.Close();
					return;
				}
				if (this.MT_Count % 5 == 0) // per 0.5 sec
				{
					// stop zombies
					{
						SSRBServerProc.StopTSRServer();
						SSRBServerProc.StopServer();
						SSRBServerProc.AbandonCurrentRunningBatch();
					}
				}
			}
			finally
			{
				this.MT_Count++;
			}
		}
	}
}


text:
<?php
namespace Bun\PDO;

use Bun\Core\Module\AbstractModule;

/**
 * Class MySQL
 *
 * @package MySQL
 */
class PDO extends AbstractModule
{
    protected $version = '0.1';
    protected $description = 'Bun PDO module';
    protected $source = 'https://github.com/jakulov/bun_pdo';
    protected $sourceType = self::MODULE_SOURCE_TYPE_GITHUB;
    protected $sourceBranch = 'master';
    protected $dependencies = array(
        'bun'
    );
    protected $config = array(
        'Pdo',
        'Container',
        'Event',
        'Logger',
    );
}


text:
SyncStartupTracker::SyncStartupTracker(Profile* profile, Observer* observer)
    : profile_(profile),
      observer_(observer) {
  ProfileSyncService* service = ProfileSyncServiceFactory::GetForProfile(
      profile_);
  if (service)
    service->AddObserver(this);

  CheckServiceState();
}

SyncStartupTracker::~SyncStartupTracker() {
  ProfileSyncService* service = ProfileSyncServiceFactory::GetForProfile(
      profile_);
  if (service)
    service->RemoveObserver(this);
}

void SyncStartupTracker::OnStateChanged() {
  CheckServiceState();
}

void SyncStartupTracker::CheckServiceState() {
  // Note: the observer may free this object so it is not allowed to access
  // this object after invoking the observer callback below.
  switch (GetSyncServiceState(profile_)) {
    case SYNC_STARTUP_ERROR:
      observer_->SyncStartupFailed();
      break;
    case SYNC_STARTUP_COMPLETE:
      observer_->SyncStartupCompleted();
      break;
    case SYNC_STARTUP_PENDING:
      // Do nothing - still waiting for sync to finish starting up.
      break;
  }
}

// static
SyncStartupTracker::SyncServiceState SyncStartupTracker::GetSyncServiceState(
    Profile* profile) {
  // If sync is disabled, treat this as a startup error.
  if (!profile->IsSyncAccessible())
    return SYNC_STARTUP_ERROR;

  ProfileSyncService* service =
      ProfileSyncServiceFactory::GetForProfile(profile);

  // If no service exists or sync is disabled, treat as a startup error.
  if (!profile->IsSyncAccessible() || !service ||
      !service->IsSyncEnabledAndLoggedIn()) {
    return SYNC_STARTUP_ERROR;
  }

  // If the sync backend has started up, notify the callback.
  if (service->sync_initialized())
    return SYNC_STARTUP_COMPLETE;

  // If the sync service has some kind of error, report to the user.
  if (service->HasUnrecoverableError())
    return SYNC_STARTUP_ERROR;

  // If we have an auth error and sync is not still waiting for new auth tokens
  // to be fetched, exit.
  if (!service->waiting_for_auth() &&
      service->GetAuthError().state() != GoogleServiceAuthError::NONE) {
    return SYNC_STARTUP_ERROR;
  }

  // No error detected yet, but the sync backend hasn't started up yet, so
  // we're in the pending state.
  return SYNC_STARTUP_PENDING;
}


text:
## Chapter.5 bpftrace

> tracer built on BPF & BCC; ideal for ad-hoc instrumentation with custom one-liners
>
> [reference guide](https://github.com/iovisor/bpftrace/blob/master/docs/reference_guide.md), [kernel analysis with bpftrace](https://lwn.net/Articles/793749/), [cheatsheet](https://www.brendangregg.com/BPF/bpftrace-cheat-sheet.html), [one-liner tuts](https://github.com/iovisor/bpftrace/blob/master/docs/tutorial_one_liners.md)

### Components

* contains doc, man-pages, examples; included bpftrace tools have `.bt` extension

* frontend uses lex & yacc to parse bpftrace, Clang for parsing structure; backend compiles to LLVM IR then BPF by LLVM libs

### Features

#### Event Sources

* Dynamic instrumentation: kernel-level `kprobe` and user-level `uprobe`

* Static instrumentation: kernel-level `tracepoint. software` and user-level `usdt via libbcc`

* Timed sampling events `profile`; Interval events `interval`

* PMC events `hardware`; Synthetic events `BEGIN, END`

#### Actions

* Filtering `predicates`; Per-event output `printf()`

* Basic Variables `global, $local, per[tid]`; Built-in Variables `pid, tid, comm, nsecs, ..`

* Associative Arrays `key[val]`; Frequency Counting `count(), ++`; Statistics `min(), max(), sum(), avg(), stats()`

* Histograms `hist(), lhist()`; Timestamps & deltas `nsecs and hash storage`

* Stack traces `kstack` for kernel & `ustack` for userspace

* Symbol resolution `ksym(), kaddr()` for kernel & `usym(), uaddr()` for userspace

* C struct navigation `->`; Array access `[]`; Shell commands `system()`

* Printing file `cat()`; Positional params `$1, $2, ..`

#### Compared to other Observability Tools

* `perf` has verbose language; supports efficient event dumping in binary format; in-kernel supparies limited to counts

* `Ftrace` has fewer dependencies; has instrumentation mode as function counts

* `Systemtap` adds its own kernel modules, proven unreliable on systems other than RHEL

* `LTTng` has optimized event dumping & analysis tools of dump

* `Application tools` limited to user-level visibility; like JVM profiler & MySQL DB profiler

### Installation

> [documentation with steps](https://github.com/iovisor/bpftrace/blob/master/INSTALL.md)

### Tools

* [list of tools with example links](https://github.com/iovisor/bpftrace#tools)

#### Highlighted Tools

* CPU: execsnoop, runqlat, runqlen, cpuwalk, offcputime

* Memory: oomkill, failts, vmscan, swapin

* File Systems: vfsstat, filelife, xfsdist

* Storage I/O: biosnoop, biolatency, bitesize, biostacks, scsilatency, nvmelatency

* Networking: tcpaccept, tcpconnect, tcpdrop,  tcpretrans, gethostlatency

* Security: ttysnoop, elfsnoop, setuids

* Languages: jnistacks, javacalls

* Applications: threadsnoop, pmheld, naptime, mysqld\_qslower

* Kernel: mlock, mheld, kmem, kpages, workq

* Containers: pidnss, blkthrot

* Hypervisors: xenhyper, cpustolen, kvmexits

* Debugging/multi-purpose: execsnoop, threadsnoop, opensnoop, killsnoop, signals

### One-Liners

* list probes: `sudo bpftrace -l 'tracepoint:syscalls:sys_enter_*'`

* whose executing what

```
% sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s %s\n", comm, str(args->argv)); }'
Attaching 1 probe...
vim /home/username/bin/go-1.16.7/bin/sh
...
```

* new processes with args

```
% sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve { join(args->argv); }'
Attaching 1 probe...
git ls-files --error-unmatch --full-name -z -- chapter-05.md
/bin/bash -c /usr/bin/zsh
...
```

* files opened: `sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'`

* count syscalls by program: `sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'`

* count syscalls by process: `sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[pid, comm] = count(); }'`

* count syscalls by probe name: `sudo bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }'`

* total `read()` bytes by process: `sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret/ { @[comm] = count(); }'`

* distribution of `read()` bytes by process: `sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read { @bytes = hist(args->ret); }'`

> filtered by PID 6763 would be

```
% sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read /pid == 6763/ { @bytes = hist(args->ret); }'
Attaching 1 probe...
^C
@bytes:
[0]                    5 |@                                                   |
[1]                    4 |                                                    |
...
```

* Kernel dynamic-tracing of read bytes `sudo bpftrace -e 'kretprobe:vfs_read { @bytes = lhist(retval, 0, 2000, 200); }'`

> above `lhist()` takes `value, min, max, step` as params for histogram

* timing `read()` in nanoseconds summarized by process name

```
% sudo bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; } kretprobe:vfs_read /@start[tid]/ { @ns[comm] = hist(nsecs - @start[tid]); delete(@start[tid]); }'
Attaching 2 probes...
^C
@ns[systemd-journal]:
[4K, 8K)               1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|

@ns[libinput-connec]:
[1K, 2K)               2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[2K, 4K)               0 |                                                    |
[4K, 8K)               0 |                                                    |
[8K, 16K)              2 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
...
```

* histogram of block I/O requests by size in bytes: `sudo bpftrace -e 'tracepoint:block:block_rq_issue { @ = hist(args->bytes); }'`

* trace disk I/O size by process

```
% sudo bpftrace -e 'tracepoint:block:block_rq_issue { printf("%d %s %s\n", pid, comm, str(args->bytes)); }'
Attaching 1 probe...
6489 kworker/u16:1
6489 kworker/u16:1
419 NetworkManager
```

* count pages paged in by process: `sudo bpftrace -e 'software:major-faults:1 { @[comm] = count(); }'`

* count page faults by process: `sudo bpftrace -e 'software:faults:1 { @[comm] = count(); }'`

* profile user-level stacks at 99Hz: `sudo bpftrace -e 'profile:hz:45 { @[ustack] = count(); }'`

> * profile FOR 1second: `sudo bpftrace -e 'profile:hz:45 { @[ustack] = count(); }  interval:s:1 { exit(); }'`
>
> * profile FOR pid 6763: `sudo bpftrace -e 'profile:hz:45 /pid == 6763/ { @[ustack] = count(); }'`

* count process level events for 5sec `sudo bpftrace -e 'tracepoint:sched:sched* { @[probe] = count(); } interval:s:5 { exit(); }'`

* count stacktraces leading to context-switch (off-CPU) events: `sudo bpftrace -e 'tracepoint:sched:sched_switch { @[kstack] = count(); }'`

### Programming

* [Kernel Struct Tracing code example](chapter-05-kernel-struct-tracing.bt)

```
% sudo bpftrace chapter-05-kernel-struct-tracing.bt
Attaching 1 probe...
open path: meminfo
open path: statm
...
```

* [Measure time in vfs\_read() kernel function](chapter-05-measure-vfs-read-time.bt)

> can be run with `bpftrace`; or just make executable if shebang is present

#### Program Structure

* series of probes with associated actions and optional filters as `probes { actions }`, `probe /filter/ { actions }`

* or just `/pattern/ { actions }`

* comments are C-like `//` & `/* ... */`

* C struct navigation `->`; C structs can be declared in some cases

* probe format `type:identifier[:identifier[...]]`; multi-purpose probes can be specified with comma-separators to execute same actions

* probe wildcards like `kprobe:vfs_*`; instrumenting too many probes may cost bad overhead so managed by `BPFTRACE_MAX_PROBES` env var *default:512*

* filter like equal `/pid == 1/`; or just `/pid/` to ensure it's non-zero; boolean operators are allowed as `/pid > 100 && pid < 1000/`

* action can be multiple separated by semicolons

* `BEGIN{ action }` &/or `END{ action }` blocks are allowed in one-liner and indented code blocks

* built-in functions be `printf()`, `exit()`, `str(char *)`, `system(format [, args ..])` (run cmd at shell)

* built-in variables are usually read-only; include `pid` for proc-id, `comm` for name, `nsecs` for timesamp, `curtask` for address of current thread's `task_struct`

* scratch variables used for temp calculations having prefix `$`; name and type is set on first assignment

* map variables use BPF map storage object having prefix `@`; key can be provided with one/more elements using maps as a hash table

```
@start[tid] = nsecs;  // simple association

@path[pid, $fd] = str(arg0);  // multi-key association
```

* map functions are special functions that can be assigned to maps or operate on them

```
@a = count();  // using per CPU map becoming special object of type count; allowing @a++

@b = sum($a);  // sums $a variable, when printed gives total

@c = hist($a);  // stores $a in a power-of-two histogram, printing bucket counts & ASCII histogram

print(@x); // printing map @x; all maps are auto-printed on BPF termination

delete(@start[tid]);  // deletes given key & its value pair

clear(@x);  // clears map @x
```

### Usage

* running `bpftrace` shows its help; `-d` && `-dd` for debug dry-run & verbose debug

> `-o file` to redirect output to a file
>
> `-e program` execute a program block
>
> `-p PID` enable USDT probes on PID

### Probe Types

#### tracepoint

* tracepoints usually provide args (for info); e.g. `tracepoint:net:netif_rx` have field `len` for packet length accessible using `args->len`

* `tracepoint:syscalls:sys_enter_read` & `tracepoint:syscalls:sys_exit_read` insrument start and end of `read()` system calls

* its args can be checked using `-l` for list & `-v` for verbose; as

```
% sudo bpftrace -lv 'tracepoint:syscalls:sys_enter_read'
tracepoint:syscalls:sys_enter_read
    int __syscall_nr
    unsigned int fd
    char __attribute__((user)) * buf
    size_t count

% sudo bpftrace -lv 'tracepoint:syscalls:sys_exit_read'
tracepoint:syscalls:sys_exit_read
    int __syscall_nr
    long ret
```

* trace enter/exit of `clone()` syscall that creates new processes; it might have multiple exits/returns (for parent & child processes)

```
% sudo bpftrace -e 'tracepoint:syscalls:sys_enter_clone {printf("-> clone() by %s PID %d\n", comm, pid); }
                      tracepoint:syscalls:sys_exit_clone { printf("<- clone() return %d, %s PID %d\n", args->ret, comm, pid); }'
Attaching 2 probes...
-> clone() by vim PID 1216
<- clone() return 9334, vim PID 1216
<- clone() return 0, vim PID 9334
```

* show `execve()` syscall `sudo bpftrace -e 't:syscalls:sys_enter_clone {printf("%s \t %s; PID %d\n", probe, comm, pid); }'`

#### usdt

* can instrument binaries/shared-libs; `sudo bpftrace -p ${PID} -l` shows all probes available over a Process (grep for `usdt`)

```
% sudo bpftrace -p 1087 -l | grep usdt ## for shell process
usdt:/proc/1087/root/usr/lib/ld-2.33.so:rtld:init_complete
usdt:/proc/1087/root/usr/lib/ld-2.33.so:rtld:init_start
...
```

#### kprobe and kretprobe

* arguments for `kprobe` are `arg0, arg1, ...argN` as unsigned 64-bit int; if pointer to a C struct then cast it (future BTF makes it automatic)

* arguments for `kretprobe` is `retval` built-in for return value which is also uint64

#### uprobe and uretprobe

* similar to usdt, binary/lib path with function name as `uprobe:/bin/bash:readline` & `uretprobe:/bin/bash:readline`

* similar to kprobe/kretprobe; `arg0, arg1..` arguments for `uprobe` & `retval` for `uretprobe`

#### software and hardware

* format of `software:event_name:count`, `software:event_name:`, `hardware:event_name:count`, `hardware:event_name:`

* s/w events similar to tracepoints but suited for count; h/w events are selection of PMCs for processor-level analysis

* to avoid overhead of too many events; sampled on count

* available s/w & h/w events depend on kernel version; some are

> Software Events
>
> * `cpu-clock` (alias: cpu, default count: 1000000); cpu wall-time clock
>
> * `task-clock` (default: 1000000); cpu task clock (increments only when task is on-CPU)
>
> * `page-faults` (alias: faults, default: 100); page faults
>
> * `context-switches` (alias: cs, default: 1000); context switches
>
> * `cpu-migrations` (default: 1); cpu thread migrations
>
> * `minor-faults` (default: 100); Minor page faults: satisfied by memory
>
> * `major-faults` (default: 1); Major page faults: satisfied by storage I/O
>
> * `alignment-faults` (default: 1); Alignment faults
>
> * `emulation-faults` (default: 1); Emulation faults
>
> * `dummy` (default: 1); Dummy event for testing
>
> * `bpf-output` (default: 1); BPF output channel
>
>
> Hardware Events
>
> * `cpu-cycles` (alias: cycles, default: 1000000); CPU clock cycles
>
> * `instructions` (default: 1000000); CPU instructions
>
> * `cache-references` (default: 1000000); CPU last level cache references
>
> * `cache-misses` (alias: branches, default: 100000); Branch instructions
>
> * `bus-cycles` (default: 100000); Bus cycles
>
> * `frontend-stalls` (default: 1000000); Processor frontend stalls (e.g. instruction fetches)
>
> * `backend-stalls` (default: 1000000); Processor backend stalls (e.g. data loads/stores)
>
> * `ref-cycles` (default: 1000000); CPU reference cycles (e.g. unscaled by turbo)

#### profile and interval

* these are timer based events: `profile:hz:rate`, `profile:s:rate`, `profile:ms:rate`, `profile:us:rate`, `interval:s:rate`, `interval:ms:rate`

### Flow Control

> * 3 type tests in bpftrace: filters, ternary, if statements
>
> * based on boolean expressions `==, !=, >, <, >=, <=, &&, ||`

* Filter: `probe /filter/ { action;s }`

* Ternary Operators: `test ? true_stmt : false_stmt`

* If Statements: `if (test) { true_stmt }`, `if (test) { true_stmt } else { false_stmt }`

> currently `else if { .. }` statements are not supported

* Unrolled Loops: avoids infinite loops; supports `unroll (count) { statements }`

> * count is an integer literal (constant) with max 20
>
> * Linux 5.3 kernel includes support for BPF bounded loops

### Operators

* assignment `=`; arithmetic `+, -, *, /`; auto-increment/decrement `++, --`

* binary and/or/xor/not `&, |, ^, !`

* shift left/right `<<, >>`

* compound operator `+=, -=, *=,/=, %=, &=, ^=, <<=, >>=`

### Variables

> Process Id `pid`, Thread Id `tid`, User Id `uid`, User name `username`, Processor Id `cpu`, Process name `comm`,
>
> Timestamp (nanosec) `nsecs`, Timestamp (nanosecs) since bpftrace init `elapsed`, Kernel Task Struct as uint64 `curtask`,
>
> Kernel Stacktrace `kstack`, User Stacktrace `ustack`, Traced Function `func`, Probe Name `probe`, Cgroup Id `cgroup`,
>
> Some probe type arg `arg0, ..argN` and other arg as `args`, Return Value for some probe types `retval`, Positional args `$1,..$N`

#### Built-ins: pid, comm, uid

* printing who's calling `setuid()` syscall

```
% sudo bpftrace -e 't:syscalls:sys_enter_setuid {printf("setuid by PID: %d (%s),\t UID %d\n", pid, comm, uid); }'
```

* can trace return value by sys_enter_exit; where '-1' is failure

```
% sudo bpftrace -e 't:syscalls:sys_exit_setuid {printf("setuid by PID %d (%s): UID %d\n", pid, comm, args->ret); }'
```

#### Built-ins: kstack, ustack

* kstack/ustack return kernel/user level stack traces as multi-line string, return upto 127 frames

```
% sudo bpftrace -e 't:block:block_rq_insert {printf("Block I/O by %s\n", kstack); }'
Attaching 1 probe...
Block I/O by
        dd_insert_requests+468
        dd_insert_requests+468
        blk_mq_sched_insert_requests+98
...
```

* stack built-ins can also be used as keys in map, freq to be counted

```
% sudo bpftrace -e 't:block:block_rq_insert {@[ustack] = count(); }'
Attaching 1 probe... ^C
@[ fsync+59 ]: 6
@[]: 180
```

#### Built-ins: Positional Parameters

* passed to program on cmd-line, accessible at position as `$1`; usage like `watchconn.bt 101` for passing pid 101

```
% sudo bpftrace -e 'BEGIN {printf("Hey %s!\n", str($1)); }' BPF
Attaching 1 probe...
Hey BPF!
^C
```

#### Scratch & Map

* Scratch like `$duration_us` used for temporary eval in [chapter-05-measure-vfs-read-time.bt](chapter-05-measure-vfs-read-time.bt)

* Map like `@n`, `@n[k]`, `@n[k1 [,k2 [,..]]]`; for storage using hash tables for consistent key-val types

### Functions

> Print formatted `printf(char *fmt [, ...])`, Print formatted time `time(char *fmt)`, Print space joined string array `join(char *arr[])`,
>
> Return string from pointer with optional length `str(char *s [, int len])`,
>
> Return kernel/user stack to limit frames deep `kstack(int l)` & `ustack(int l)`,
>
> Resolve kernel/userspace address to return string symbol using `ksym(void *p)` & `usym(void *p)` resp.,
>
> Resolve kernel/userspace symbol to an address using `kaddr(char *name)` & `uaddr(char *name)` resp.,
>
> Returns value stored in named register `reg(char *name)`, Returns string for IP `ntop([int af,] int addr)`,
>
> Prints contents of file `cat(char *file)`, Exits bpftrace `exit()`; `cgroupid(char *path)` to resolve Cgroup Id

#### `printf()`

* similar to C syntax; allows escape sequences; field descriptions `%[-][width]type` where `-` makes left-justified (default: right)

> * uint `%u`, int `%d`, ulong `%lu`, long `%ld`, unsigned long long `%llu`, long long `%lld`, ushort `%hu`, short `%hd`
>
> * hexadecimal: uint `%x`, ulong `%lx`, ulong long `%llx`
>
> * char `%c`, string `%s`

* example to print 16-char wide `comm` & 6-char wide left-justified `pid` via `printf("%16s %-6d\n", comm, pid);`

#### `join()`

* e.g. attempted execution of commands with their args using `sudo bpftrace -e 't:syscalls:sys_enter_execve { join(args->argv); }'`

* e.g. checking if execution attempt succeeded `% sudo bpftrace -e 't:syscalls:sys_exit_execve { printf("%s %-d\n", comm, args->ret); }'`

> a failed attempt means invocation of a command failed, not necessarily for failure faced due to args within the command

#### `str()`

* default string limit is 64bytes; tunable via `BPFTRACE_STRLEN`

* max allowed 200 bytes until stored in BPF stack; will increase once moved to BPF maps

#### `kstack()` and `ustack()`

* similar to kstack/ustack, with accepting limit: `kstack(limit)`, `kstack(mode[, limit])`, `ustack(limit)`, `ustack(mode[, limit])`

* show top3 kernel frames that led to creating block I/O; max limit is 1024 frames

```
% sudo bpftrace -e 't:block:block_rq_insert { @[kstack(3), comm] = count(); }'
Attaching 1 probe... ^C
@[
    dd_insert_requests+468
    dd_insert_requests+468
    blk_mq_sched_insert_requests+98
, kworker/u16:1]: 1
...
```

> mode arg allows stack output to be formatted differently; supported default `bpftrace` & `perf`

```
% sudo bpftrace -e 'k:do_nanosleep { printf("%s", ustack(perf)); }'
Attaching 1 probe...
	7fe6f239ba95 __GI___clock_nanosleep+117 (/usr/lib/libc-2.33.so)
...
```

#### `ksym()` and `usym()`

* e.g. a function pointer arg as `@[args->function] = count() ;` can display names if used as `@[ksym(args->function)] = count() ;`

* `usym` relies on symbol table in binaries for symbol lookup

#### `kaddr()` and `uaddr()`

* can look for a user-space symbol say `ps1_prompt` when a function is called say `bash:readline` by dereferencing as `sudo bpftrace -e 'uprobe:bash:readline { printf("%s\n", str(*uaddr("ps1_prompt"))); }'`

#### `kptr(void *p)` and `uptr(void *p)`

* generally address space of a pointer gets inferred; but there are some corener cases as kernel func dealing with userspace pointers

```
% sudo bpftrace -e 'k:do_sys_open { printf("%s\n", str(uptr(arg1))); }'  ## usage
```

#### `system()` and `signal()` and `cat()`

* executes command at shell, syntax `system(char *fmt [, args...])` and require `--unsafe` option

> example, calling `ps` to print details on PID calling `nanosleep()`

```
sudo bpftrace --unsafe -e 't:syscalls:sys_enter_nanosleep { system("ps -p %d\n", pid); }'
```

* if used for a frequent event, it will load up more processes per event onto CPU causing overload

* `signal` requires unsafe as well and can send a specified signal to current task `sudo bpftrace -e 'k:f { signal("KILL"); }'`

* `cat` prints file content as

```
% sudo bpftrace -e 't:syscalls:sys_enter_sendmsg { printf("%s => ", comm);
                                                   cat("/proc/%d/cmdline", pid);
                                                   print("\n"); }'
Attaching 1 probe...
systemd-timesyn => /usr/lib/systemd/systemd-timesyncd
systemd-udevd => /usr/lib/systemd/systemd-udevd
...
```

#### `exit()`

```
sudo bpftrace -e 't:syscalls:sys_enter_read { @reads = count() } interval:s:5 { exit(); }'
```

### Map Functions

> Count occurences `count()`; Sum the value `sum(int n)`; Averages the value `avg(int n)`;
>
> Minimum value `min(int n)`; Maximum value `max(int n)`; Print map with optional limits `print(@m [,top [,div]])`
>
> Return count, avg & total `stats(int n)`; Print pow-2 histogram `hist(int n)`; Print linear histogram `lhist(int n, min, max, step)`;
>
> Delete map k/v pair `delete(@m[k])`; Delete all map keys `clear(@m)`; Sets all map values to zero `zero(@m)`

* examples

```
% sudo bpftrace -e 't:block:* { @[probe] = count() } interval:s:5 { exit(); }'
Attaching 19 probes...
@[tracepoint:block:block_plug]: 1
@[tracepoint:block:block_unplug]: 1
...
```

* e.g. print per-interval rate

```
% sudo bpftrace -e 't:block:block_rq_* { @[probe] = count() } interval:s:5 { print(@); print("\n"); clear(@); }'
Attaching 7 probes...
@[tracepoint:block:block_rq_issue]: 5
@[tracepoint:block:block_rq_complete]: 5

@[tracepoint:block:block_rq_insert]: 1
@[tracepoint:block:block_rq_issue]: 8
@[tracepoint:block:block_rq_complete]: 9
...
```

> basic functionality can also be done via `perf stat`

* total bytes read `% sudo bpftrace -e 't:syscalls:sys_exit_read /args->ret > 0/ { @bytes = sum(args->ret); }'`

* error counts are better with freq count of error codes

```
% sudo bpftrace -e 't:syscalls:sys_exit_read /args->ret < 0/ { @[- args->ret] = count(); }'
Attaching 1 probe...^C
@[11]: 9                          ### Error Code: 11 (EAGAIN) is for Try Again in read()
```

* printing time in microsecond using `div`

```
% sudo bpftrace -e 'k:vfs_read { @start[tid] = nsecs; }
                    kr:vfs_read /@start[tid]/ { @us[comm] = sum(nsecs - @start[tid]); delete(@start[tid]); }
                    END { print(@us, 0, 1000); clear(@us); clear(@start); }'
Attaching 3 probes...^C
@us[Monitor thread]: 2
@us[systemd-journal]: 5
@us[ls]: 12
@us[git]: 257
@us[tail]: 14356
...
```

### Future Work

* experimental in Linux 5.3; C style `while` loops as

```
% sudo bpftrace -e 'i:ms:100 { $i = 0; while($i <= 10) {printf("%d ", $i); $i++;} exit();}'
Attaching 1 probe...
0 1 2 3 4 5 6 7 8 9 10
```

* `ply` BPF front-end provides high-level interface without LLVM/Clang depenedency (but struct navigation & including header files not possible)

### Internals

* bpftrace language defined by lex & yacc files; output an AST

* Tracepoint & Clang parsers process structs; Semantic Analyzer checks use of language

* AST nodes converted to LLVM IR, finally compiled to BPF bytecode

### Debugging

* `printf()` could be used to leave breadcrumbs in run

* `-d` prints AST & LLVM IR; `-v` prints BPF bytecode

> [Next Chapter 6. CPUs | Part.II: Using BPF Tools](./chapter-06.md)

---


text:
"""File Access Model"""
from __future__ import (absolute_import, print_function,
                        division, unicode_literals)

import os

from sqlalchemy import Column, Integer, Text, TIMESTAMP
from sqlalchemy import PrimaryKeyConstraint, ForeignKeyConstraint

from ...utils.prolog import PrologDescription, PrologTrial, PrologAttribute
from ...utils.prolog import PrologRepr, PrologTimestamp, PrologNullable
from ...utils.prolog import PrologNullableRepr

from .. import relational, persistence_config

from .base import AlchemyProxy, proxy_class, proxy

@proxy_class
class FileAccess(AlchemyProxy):
    """Represent a file access"""

    hide_timestamp = False

    __tablename__ = "file_access"
    __table_args__ = (
        PrimaryKeyConstraint("trial_id", "id"),
        ForeignKeyConstraint(["trial_id", "function_activation_id"],
                             ["function_activation.trial_id",
                              "function_activation.id"], ondelete="CASCADE"),
        ForeignKeyConstraint(["trial_id"], ["trial.id"], ondelete="CASCADE"),
    )
    trial_id = Column(Integer, index=True)
    id = Column(Integer, index=True)                                             # pylint: disable=invalid-name
    name = Column(Text)
    mode = Column(Text)
    buffering = Column(Text)
    content_hash_before = Column(Text)
    content_hash_after = Column(Text)
    timestamp = Column(TIMESTAMP)
    function_activation_id = Column(Integer, index=True)

    # Relationship attributes (see relationships.py):
    #   trial: 1 Trial
    #   activation: 1 Activation

    prolog_description = PrologDescription("access", (
        PrologTrial("trial_id", link="activation.trial_id"),
        PrologAttribute("id", fn=lambda obj: "f{}".format(obj.id)),
        PrologRepr("name"),
        PrologRepr("mode"),
        PrologNullableRepr("content_hash_before"),
        PrologNullableRepr("content_hash_after"),
        PrologTimestamp("timestamp"),
        PrologNullable("activation_id", attr_name="function_activation_id",
                       link="activation.id"),
    ), description=(
        "informs that in a given trial (*trial_id*),\n"
        "a file *name*\n"
        "was accessed by a function activation (*activation_id*)\n"
        "in a specific read or write *mode*\n"
        "at a specific *timestamp*.\n"
        "The content of the file\n"
        "was captured before (*content_hash_before*)\n"
        "and after (*content_hash_after*) the access."
    ))

    @property
    def stack(self):
        """Return the activation stack since the beginning of execution"""
        stack = []
        activation = self.activation
        while activation:
            name = activation.name
            activation = activation.caller
            if activation:
                stack.insert(0, name)
        if not stack or stack[-1] != "open":
            stack.append(" ... -> open")
        return " -> ".join(stack)

    @property
    def brief(self):
        """Brief description of file access"""
        result = "({0.mode}) {0.name}".format(self)
        if self.content_hash_before is None:
            result += " (new)"
        return result

    @property
    def activation_id(self):
        return self.function_activation_id

    @property
    def is_internal(self):
        return (
            not os.path.isabs(self.name) or
            persistence_config.base_path in self.name
        )

    @classmethod  # query
    def find_by_name_and_time(cls, name, timestamp, trial=None,
                              session=None):
        """Return the first access according to name and timestamp

        Arguments:
        name -- specify the desired file
        timestamp -- specify the start of finish time of trial

        Keyword Arguments:
        trial -- limit search in a specific trial_id
        """
        model = cls.m
        session = session or relational.session
        query = (
            session.query(model)
            .filter(
                (model.name == name) &
                (model.timestamp.like(timestamp + "%"))
            ).order_by(model.timestamp)
        )
        if trial:
            query = query.filter(model.trial_id == trial)
        return proxy(query.first())

    def __key(self):
        return (self.name, self.content_hash_before, self.content_hash_after,
                self.mode)

    def __hash__(self):
        return hash(self.__key())

    def __eq__(self, other):
        if not isinstance(other, FileAccess):
            return False
        return (
            (self.content_hash_before == other.content_hash_before)
            and (self.content_hash_after == other.content_hash_after)
        )

    def show(self, _print=print):
        """Show object

        Keyword arguments:
        _print -- custom print function (default=print)
        """
        result = """\
            Name: {f.name}
            Mode: {f.mode}
            Buffering: {f.buffering}
            Content hash before: {f.content_hash_before}
            Content hash after: {f.content_hash_after}
            """
        if not self.hide_timestamp:
            result += """Timestamp: {f.timestamp}
            """
        result += """Function: {f.stack}\
            """
        _print(result.format(f=self))

    def __repr__(self):
        return "FileAccess({0.trial_id}, {0.id}, {0.name}, {0.mode})".format(
            self)

class UniqueFileAccess(FileAccess):

    def __key(self):
        return self.id

    def __eq__(self, other):
        if not isinstance(other, FileAccess):
            return False
        return (self.id == other.id)

    def __hash__(self):
        return hash(self.__key())


text:
package sandbox;

import org.testng.annotations.Test;

/**
 * Created by taty on 31.07.2017.
 */
public class SquareTests {

    @Test
    public void testArea(){
        Square a = new Square(5);
        assert a.area() == 25;
    }
}


text:
import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';

import { Sale } from '../models/sale'

@Injectable()
export class SalesProvider{

    constructor(private http: Http){

    }

    new(products:Array<any>, saleOff:number): Promise<any> {
        let self = this;

        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        headers.append('Authorization', localStorage.getItem('user_token'));

        let body = JSON.stringify({'token': localStorage.getItem('user_token'), 'products': products, 'saleOff': saleOff});

        return this.http
        .post('http://' + localStorage.getItem('hostAPI') + ':' + localStorage.getItem('portAPI') + '/sales/new', body, {headers:headers})
        .map((response) => {
            let data = response.json();
            console.log(data);
            return data;
        })
        .toPromise();
    }

    addPayment(sale: string, type: number, payment: any){
        let self = this;

        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        headers.append('Authorization', localStorage.getItem('user_token'));

        let body = JSON.stringify({'sale': sale, 'type': type, 'payment': payment});

        return this.http
        .post('http://' + localStorage.getItem('hostAPI') + ':' + localStorage.getItem('portAPI') + '/sales/addPayment', body, {headers:headers})
        .map((response) => {
            let data = response.json();
            return data;
        })
        .toPromise();
    }

    details(uuid: string): Promise<any>{
        let self = this;

        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        headers.append('Authorization', localStorage.getItem('user_token'));

        return this.http
        .get('http://' + localStorage.getItem('hostAPI') + ':' + localStorage.getItem('portAPI') + '/sales/details/' + uuid, {headers:headers})
        .map((response) => {
            let data = response.json();
            return data;
        })
        .toPromise();
    }
}


text:
 .. Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

 ..   http://www.apache.org/licenses/LICENSE-2.0

 .. Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

Changelog
---------

1.2.0
.....

Features
~~~~~~~~

* ``Undeprecate private_key option in SFTPHook (#15348)``
* ``Add logs to show last modified in SFTP, FTP and Filesystem sensor (#15134)``

1.1.1
.....

Bug fixes
~~~~~~~~~

* ``Corrections in docs and tools after releasing provider RCs (#14082)``

1.1.0
.....

Updated documentation and readme files.

Features
~~~~~~~~

* ``Add retryer to SFTP hook connection (#13065)``

1.0.0
.....

Initial version of the provider.


text:
package bootstrap

import (
	"fmt"
	"strings"
)

// This file handles correctly identifying the default release image, which is expected to be
// replaced in the binary post-compile after being extracted from a payload. The expected modification is:
//
// 1. Extract a release binary from the installer image referenced within the release image
// 2. Identify the release image pull spec, add a NUL terminator byte (0x00) to the end, calculate length
// 3. Length must be less than 300 bytes
// 4. Search through the installer binary looking for `\x00_RELEASE_IMAGE_LOCATION_\x00<PADDING_TO_LENGTH>`
//    where padding is the ASCII character X and length is the total length of the image
// 5. Overwrite that chunk of the bytes if found, otherwise return error.
//
// On start the installer examines the constant and if it has been modified from the default the installer
// will use that image.

var (
	// defaultReleaseImageOriginal is the value served when defaultReleaseImagePadded is unmodified.
	defaultReleaseImageOriginal = "registry.svc.ci.openshift.org/openshift/origin-release:v4.0"
	// defaultReleaseImagePadded may be replaced in the binary with a pull spec that overrides defaultReleaseImage as
	// a null-terminated string within the allowed character length. This allows a distributor to override the payload
	// location without having to rebuild the source.
	defaultReleaseImagePadded = "\x00_RELEASE_IMAGE_LOCATION_\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00"
	defaultReleaseImagePrefix = "\x00_RELEASE_IMAGE_LOCATION_\x00"
	defaultReleaseImageLength = len(defaultReleaseImagePadded)
)

// defaultReleaseImage abstracts how the binary loads the default release payload. We want to lock the binary
// to the
func defaultReleaseImage() (string, error) {
	if strings.HasPrefix(defaultReleaseImagePadded, defaultReleaseImagePrefix) {
		// the defaultReleaseImagePadded constant hasn't been altered in the binary, fall back to the default
		return defaultReleaseImageOriginal, nil
	}
	nullTerminator := strings.IndexByte(defaultReleaseImagePadded, '\x00')
	if nullTerminator == -1 {
		// the binary has been altered, but we didn't find a null terminator within the constant which is an error
		return "", fmt.Errorf("release image location was replaced but without a null terminator before %d bytes", defaultReleaseImageLength)
	}
	if nullTerminator > len(defaultReleaseImagePadded) {
		// the binary has been altered, but the null terminator is *longer* than the constant encoded in the binary
		return "", fmt.Errorf("release image location contains no null-terminator and constant is corrupted")
	}
	pullspec := defaultReleaseImagePadded[:nullTerminator]
	if len(pullspec) == 0 {
		// the binary has been altered, but the replaced image is empty which is incorrect
		return "", fmt.Errorf("release image location is empty, this binary was incorrectly generated")
	}
	return pullspec, nil
}


text:
package io.domisum.lib.auxiliumlib.config;

import com.google.gson.JsonParseException;
import io.domisum.lib.auxiliumlib.PHR;
import io.domisum.lib.auxiliumlib.annotations.API;
import io.domisum.lib.auxiliumlib.util.FileUtil;
import io.domisum.lib.auxiliumlib.util.FileUtil.FileType;
import io.domisum.lib.auxiliumlib.util.ReflectionUtil;
import io.domisum.lib.auxiliumlib.util.StringListUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@API
public abstract class ConfigObjectLoader<T extends ConfigObject>
{

	private final Logger logger = LoggerFactory.getLogger(getClass());

	// CONSTANT METHODS
	protected abstract String OBJECT_NAME();

	protected abstract String FILE_EXTENSION();

	@API
	protected String OBJECT_NAME_PLURAL()
	{
		return OBJECT_NAME()+"s";
	}

	protected boolean LOG_INDIVIDUAL_OBJECT_LOADS()
	{
		return true;
	}

	// LOADING
	public ConfigObjectRegistry<T> load(File configDirectory)
		throws ConfigException
	{
		logger.info("Loading {}...", OBJECT_NAME_PLURAL());

		var files = FileUtil.listFilesRecursively(configDirectory, FileType.FILE);
		var filesOrdered = files.stream()
			.sorted(Comparator.comparing(File::getPath))
			.collect(Collectors.toList());

		var configObjectsById = new HashMap<String, T>();
		for(var file : filesOrdered)
		{
			if(getPathInDir(configDirectory, file).startsWith(".git"))
				continue;

			T configObject = readConfigObject(file);

			if(configObjectsById.containsKey(configObject.getStringId()))
				throw new ConfigException(PHR.r("Duplicate config object id '{}'. Duplicate file: {}",
					configObject.getId(), file));
			configObjectsById.put(configObject.getStringId(), configObject);
		}

		if(configObjectsById.isEmpty())
			logger.info("(There are no {})", OBJECT_NAME_PLURAL());

		var configObjectIds = configObjectsById.keySet();
		logger.info("...Loading {} done, loaded {}: [{}]",
			OBJECT_NAME_PLURAL(), configObjectsById.size(), StringListUtil.list(configObjectIds));

		return new ConfigObjectRegistry<>(configObjectsById);
	}

	private String getPathInDir(File directory, File file)
	{
		String configDirPath = directory.getAbsoluteFile().getPath();
		String filePath = file.getAbsoluteFile().getPath();

		String pathInDir = filePath.substring(configDirPath.length());
		pathInDir = FileUtil.replaceDelimitersWithForwardSlash(pathInDir);
		if(pathInDir.startsWith("/"))
			pathInDir = pathInDir.substring(1);

		return pathInDir;
	}

	private T readConfigObject(File file)
		throws ConfigException
	{
		String fileExtension = FileUtil.getCompositeExtension(file);
		if(!getPureFileExtension().equalsIgnoreCase(fileExtension))
			throw new ConfigException(PHR.r(
				"Config directory of {} contains file with wrong extension: '{}' (expected extension: '{}')",
				OBJECT_NAME_PLURAL(), file.getName(), getPureFileExtension()));
		try
		{
			String id = FileUtil.getNameWithoutCompositeExtension(file);
			String fileContent = FileUtil.readString(file);
			return createConfigObject(id, fileContent);
		}
		catch(JsonParseException|ConfigException e)
		{
			String message = PHR.r("Invalid configuration of {} from file '{}'", OBJECT_NAME(), file.getName());
			throw new ConfigException(message, e);
		}
	}

	private String getPureFileExtension()
	{
		String fileExtension = FILE_EXTENSION();
		if(fileExtension.startsWith("."))
			fileExtension = fileExtension.substring(1);

		return fileExtension;
	}

	private T createConfigObject(String id, String fileContent)
		throws ConfigException
	{
		var configObject = deserialize(fileContent);

		ReflectionUtil.injectValue(configObject, "id", id);
		for(var dependency : getDependenciesToInject().entrySet())
			ReflectionUtil.injectValue(configObject, dependency.getKey(), dependency.getValue());

		configObject.validate();

		if(LOG_INDIVIDUAL_OBJECT_LOADS())
			logger.info("Loaded {} {}", OBJECT_NAME(), configObject);
		return configObject;
	}

	// CREATE
	protected abstract T deserialize(String configContent)
		throws ConfigException;

	protected abstract Map<Class<?>, Object> getDependenciesToInject();

}


text:
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/logging.h"

#ifdef BASE_CHECK_H_
#error "logging.h should not include check.h"
#endif

#include <limits.h>
#include <stdint.h>

#include <atomic>
#include <memory>
#include <tuple>
#include <vector>

#include "base/base_export.h"
#include "base/debug/crash_logging.h"
#include "base/immediate_crash.h"
#include "base/pending_task.h"
#include "base/strings/string_piece.h"
#include "base/task/common/task_annotator.h"
#include "base/trace_event/base_tracing.h"
#include "build/build_config.h"

#if !BUILDFLAG(IS_NACL)
#include "base/auto_reset.h"
#include "base/debug/crash_logging.h"
#endif  // !BUILDFLAG(IS_NACL)

#if defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
#include "base/debug/leak_annotations.h"
#endif  // defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)

#if BUILDFLAG(IS_WIN)
#include <io.h>
#include <windows.h>
typedef HANDLE FileHandle;
// Windows warns on using write().  It prefers _write().
#define write(fd, buf, count) _write(fd, buf, static_cast<unsigned int>(count))
// Windows doesn't define STDERR_FILENO.  Define it here.
#define STDERR_FILENO 2

#elif BUILDFLAG(IS_APPLE)
#include <CoreFoundation/CoreFoundation.h>
#include <mach-o/dyld.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <os/log.h>

#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#if BUILDFLAG(IS_NACL)
#include <sys/time.h>  // timespec doesn't seem to be in <time.h>
#endif
#include <time.h>
#endif

#if BUILDFLAG(IS_FUCHSIA)
#include "base/fuchsia/scoped_fx_logger.h"
#endif

#if BUILDFLAG(IS_ANDROID)
#include <android/log.h>
#endif

#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include <errno.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "base/process/process_handle.h"
#define MAX_PATH PATH_MAX
typedef FILE* FileHandle;
#endif

#include <algorithm>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <ostream>
#include <string>
#include <utility>

#include "base/base_switches.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/containers/stack.h"
#include "base/debug/activity_tracker.h"
#include "base/debug/alias.h"
#include "base/debug/debugger.h"
#include "base/debug/stack_trace.h"
#include "base/debug/task_trace.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/test/scoped_logging_settings.h"
#include "base/threading/platform_thread.h"
#include "base/vlog.h"
#include "build/chromeos_buildflags.h"

#if BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#endif

#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include "base/posix/safe_strerror.h"
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "base/files/scoped_file.h"
#endif

namespace logging {

namespace {

int g_min_log_level = 0;

#if BUILDFLAG(USE_RUNTIME_VLOG)
// NOTE: Once |g_vlog_info| has been initialized, it might be in use
// by another thread. Never delete the old VLogInfo, just create a second
// one and overwrite. We need to use leak-san annotations on this intentional
// leak.
//
// This can be read/written on multiple threads. In tests we don't see that
// causing a problem as updates tend to happen early. Atomic ensures there are
// no problems. To avoid some of the overhead of Atomic, we use
// |load(std::memory_order_acquire)| and |store(...,
// std::memory_order_release)| when reading or writing. This guarantees that the
// referenced object is available at the time the |g_vlog_info| is read and that
// |g_vlog_info| is updated atomically.
//
// Do not access this directly. You must use |GetVlogInfo|, |InitializeVlogInfo|
// and/or |ExchangeVlogInfo|.
std::atomic<VlogInfo*> g_vlog_info = nullptr;

VlogInfo* GetVlogInfo() {
  return g_vlog_info.load(std::memory_order_acquire);
}

// Sets g_vlog_info if it is not already set. Checking that it's not already set
// prevents logging initialization (which can come late in test setup) from
// overwriting values set via ScopedVmoduleSwitches.
bool InitializeVlogInfo(VlogInfo* vlog_info) {
  VlogInfo* previous_vlog_info = nullptr;
  return g_vlog_info.compare_exchange_strong(previous_vlog_info, vlog_info);
}

VlogInfo* ExchangeVlogInfo(VlogInfo* vlog_info) {
  return g_vlog_info.exchange(vlog_info);
}

// Creates a VlogInfo from the commandline if it has been initialized and if it
// contains relevant switches, otherwise this returns |nullptr|.
std::unique_ptr<VlogInfo> VlogInfoFromCommandLine() {
  if (!base::CommandLine::InitializedForCurrentProcess())
    return nullptr;
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (!command_line->HasSwitch(switches::kV) &&
      !command_line->HasSwitch(switches::kVModule)) {
    return nullptr;
  }
#if defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
  // See comments on |g_vlog_info|.
  ScopedLeakSanitizerDisabler lsan_disabler;
#endif  // defined(LEAK_SANITIZER)
  return std::make_unique<VlogInfo>(
      command_line->GetSwitchValueASCII(switches::kV),
      command_line->GetSwitchValueASCII(switches::kVModule), &g_min_log_level);
}

// If the commandline is initialized for the current process this will
// initialize g_vlog_info. If there are no VLOG switches, it will initialize it
// to |nullptr|.
void MaybeInitializeVlogInfo() {
  if (base::CommandLine::InitializedForCurrentProcess()) {
    std::unique_ptr<VlogInfo> vlog_info = VlogInfoFromCommandLine();
    if (vlog_info) {
      // VlogInfoFromCommandLine is annotated with ScopedLeakSanitizerDisabler
      // so it's allowed to leak. If the object was installed, we release it.
      if (InitializeVlogInfo(vlog_info.get())) {
        vlog_info.release();
      }
    }
  }
}
#endif  // BUILDFLAG(USE_RUNTIME_VLOG)

#if !BUILDFLAG(USE_RUNTIME_VLOG) && DCHECK_IS_ON()

// Warn developers that vlog command line settings are being ignored.
void MaybeWarnVmodule() {
  if (base::CommandLine::InitializedForCurrentProcess()) {
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
    if (command_line->HasSwitch(switches::kV) ||
        command_line->HasSwitch(switches::kVModule)) {
      LOG(WARNING)
          << "--" << switches::kV << " and --" << switches::kVModule
          << " are currently ignored. See comments in base/logging.h on "
             "proper usage of USE_RUNTIME_VLOG.";
    }
  }
}

#endif  // !BUILDFLAG(USE_RUNTIME_VLOG) && DCHECK_IS_ON()

const char* const log_severity_names[] = {"INFO", "WARNING", "ERROR", "FATAL"};
static_assert(LOGGING_NUM_SEVERITIES == std::size(log_severity_names),
              "Incorrect number of log_severity_names");

const char* log_severity_name(int severity) {
  if (severity >= 0 && severity < LOGGING_NUM_SEVERITIES)
    return log_severity_names[severity];
  return "UNKNOWN";
}

// Specifies the process' logging sink(s), represented as a combination of
// LoggingDestination values joined by bitwise OR.
uint32_t g_logging_destination = LOG_DEFAULT;

#if BUILDFLAG(IS_CHROMEOS)
// Specifies the format of log header for chrome os.
LogFormat g_log_format = LogFormat::LOG_FORMAT_SYSLOG;
#endif

#if BUILDFLAG(IS_FUCHSIA)
// Retains system logging structures.
base::ScopedFxLogger& GetScopedFxLogger() {
  static base::NoDestructor<base::ScopedFxLogger> logger;
  return *logger;
}
#endif

// For LOGGING_ERROR and above, always print to stderr.
const int kAlwaysPrintErrorLevel = LOGGING_ERROR;

// Which log file to use? This is initialized by InitLogging or
// will be lazily initialized to the default value when it is
// first needed.
using PathString = base::FilePath::StringType;
PathString* g_log_file_name = nullptr;

// This file is lazily opened and the handle may be nullptr
FileHandle g_log_file = nullptr;

// What should be prepended to each message?
bool g_log_process_id = false;
bool g_log_thread_id = false;
bool g_log_timestamp = true;
bool g_log_tickcount = false;
const char* g_log_prefix = nullptr;

// Should we pop up fatal debug messages in a dialog?
bool show_error_dialogs = false;

// An assert handler override specified by the client to be called instead of
// the debug message dialog and process termination. Assert handlers are stored
// in stack to allow overriding and restoring.
base::stack<LogAssertHandlerFunction>& GetLogAssertHandlerStack() {
  static base::NoDestructor<base::stack<LogAssertHandlerFunction>> instance;
  return *instance;
}

// A log message handler that gets notified of every log message we process.
LogMessageHandlerFunction g_log_message_handler = nullptr;

uint64_t TickCount() {
#if BUILDFLAG(IS_WIN)
  return GetTickCount();
#elif BUILDFLAG(IS_FUCHSIA)
  return static_cast<uint64_t>(
      zx_clock_get_monotonic() /
      static_cast<zx_time_t>(base::Time::kNanosecondsPerMicrosecond));
#elif BUILDFLAG(IS_APPLE)
  return mach_absolute_time();
#elif BUILDFLAG(IS_NACL)
  // NaCl sadly does not have _POSIX_TIMERS enabled in sys/features.h
  // So we have to use clock() for now.
  return clock();
#elif BUILDFLAG(IS_POSIX)
  struct timespec ts;
  clock_gettime(CLOCK_MONOTONIC, &ts);

  uint64_t absolute_micro = static_cast<uint64_t>(ts.tv_sec) * 1000000 +
                            static_cast<uint64_t>(ts.tv_nsec) / 1000;

  return absolute_micro;
#endif
}

void DeleteFilePath(const PathString& log_name) {
#if BUILDFLAG(IS_WIN)
  DeleteFile(log_name.c_str());
#elif BUILDFLAG(IS_NACL)
  // Do nothing; unlink() isn't supported on NaCl.
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  unlink(log_name.c_str());
#else
#error Unsupported platform
#endif
}

PathString GetDefaultLogFile() {
#if BUILDFLAG(IS_WIN)
  // On Windows we use the same path as the exe.
  wchar_t module_name[MAX_PATH];
  GetModuleFileName(nullptr, module_name, MAX_PATH);

  PathString log_name = module_name;
  PathString::size_type last_backslash = log_name.rfind('\\', log_name.size());
  if (last_backslash != PathString::npos)
    log_name.erase(last_backslash + 1);
  log_name += FILE_PATH_LITERAL("debug.log");
  return log_name;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  // On other platforms we just use the current directory.
  return PathString("debug.log");
#endif
}

// We don't need locks on Windows for atomically appending to files. The OS
// provides this functionality.
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)

base::Lock& GetLoggingLock() {
  static base::NoDestructor<base::Lock> lock;
  return *lock;
}

#endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)

// Called by logging functions to ensure that |g_log_file| is initialized
// and can be used for writing. Returns false if the file could not be
// initialized. |g_log_file| will be nullptr in this case.
bool InitializeLogFileHandle() {
  if (g_log_file)
    return true;

  if (!g_log_file_name) {
    // Nobody has called InitLogging to specify a debug log file, so here we
    // initialize the log file name to a default.
    g_log_file_name = new PathString(GetDefaultLogFile());
  }

  if ((g_logging_destination & LOG_TO_FILE) == 0)
    return true;

#if BUILDFLAG(IS_WIN)
  // The FILE_APPEND_DATA access mask ensures that the file is atomically
  // appended to across accesses from multiple threads.
  // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364399(v=vs.85).aspx
  // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
  g_log_file = CreateFile(g_log_file_name->c_str(), FILE_APPEND_DATA,
                          FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
                          OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
  if (g_log_file == INVALID_HANDLE_VALUE || g_log_file == nullptr) {
    // We are intentionally not using FilePath or FileUtil here to reduce the
    // dependencies of the logging implementation. For e.g. FilePath and
    // FileUtil depend on shell32 and user32.dll. This is not acceptable for
    // some consumers of base logging like chrome_elf, etc.
    // Please don't change the code below to use FilePath.
    // try the current directory
    wchar_t system_buffer[MAX_PATH];
    system_buffer[0] = 0;
    DWORD len = ::GetCurrentDirectory(std::size(system_buffer), system_buffer);
    if (len == 0 || len > std::size(system_buffer))
      return false;

    *g_log_file_name = system_buffer;
    // Append a trailing backslash if needed.
    if (g_log_file_name->back() != L'\\')
      *g_log_file_name += FILE_PATH_LITERAL("\\");
    *g_log_file_name += FILE_PATH_LITERAL("debug.log");

    g_log_file = CreateFile(g_log_file_name->c_str(), FILE_APPEND_DATA,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
                            OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
    if (g_log_file == INVALID_HANDLE_VALUE || g_log_file == nullptr) {
      g_log_file = nullptr;
      return false;
    }
  }
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  g_log_file = fopen(g_log_file_name->c_str(), "a");
  if (g_log_file == nullptr)
    return false;
#else
#error Unsupported platform
#endif

  return true;
}

void CloseFile(FileHandle log) {
#if BUILDFLAG(IS_WIN)
  CloseHandle(log);
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  fclose(log);
#else
#error Unsupported platform
#endif
}

void CloseLogFileUnlocked() {
  if (!g_log_file)
    return;

  CloseFile(g_log_file);
  g_log_file = nullptr;

  // If we initialized logging via an externally-provided file descriptor, we
  // won't have a log path set and shouldn't try to reopen the log file.
  if (!g_log_file_name)
    g_logging_destination &= ~LOG_TO_FILE;
}

#if BUILDFLAG(IS_FUCHSIA)
inline FuchsiaLogSeverity LogSeverityToFuchsiaLogSeverity(
    LogSeverity severity) {
  switch (severity) {
    case LOGGING_INFO:
      return FUCHSIA_LOG_INFO;
    case LOGGING_WARNING:
      return FUCHSIA_LOG_WARNING;
    case LOGGING_ERROR:
      return FUCHSIA_LOG_ERROR;
    case LOGGING_FATAL:
      // Don't use FX_LOG_FATAL, otherwise fx_logger_log() will abort().
      return FUCHSIA_LOG_ERROR;
  }
  if (severity > -3) {
    // LOGGING_VERBOSE levels 1 and 2.
    return FUCHSIA_LOG_DEBUG;
  }
  // LOGGING_VERBOSE levels 3 and higher, or incorrect levels.
  return FUCHSIA_LOG_TRACE;
}
#endif  // defined (OS_FUCHSIA)

void WriteToFd(int fd, const char* data, size_t length) {
  size_t bytes_written = 0;
  long rv;
  while (bytes_written < length) {
    rv = HANDLE_EINTR(write(fd, data + bytes_written, length - bytes_written));
    if (rv < 0) {
      // Give up, nothing we can do now.
      break;
    }
    bytes_written += static_cast<size_t>(rv);
  }
}

void SetLogFatalCrashKey(LogMessage* log_message) {
#if !BUILDFLAG(IS_NACL)
  // In case of an out-of-memory condition, this code could be reentered when
  // constructing and storing the key. Using a static is not thread-safe, but if
  // multiple threads are in the process of a fatal crash at the same time, this
  // should work.
  static bool guarded = false;
  if (guarded)
    return;

  base::AutoReset<bool> guard(&guarded, true);

  static auto* const crash_key = base::debug::AllocateCrashKeyString(
      "LOG_FATAL", base::debug::CrashKeySize::Size1024);
  base::debug::SetCrashKeyString(crash_key, log_message->BuildCrashString());

#endif  // !BUILDFLAG(IS_NACL)
}

std::string BuildCrashString(const char* file,
                             int line,
                             const char* message_without_prefix) {
  // Only log last path component.
  if (file) {
    const char* slash = strrchr(file,
#if BUILDFLAG(IS_WIN)
                                '\\'
#else
                                '/'
#endif  // BUILDFLAG(IS_WIN)
    );
    if (slash) {
      file = slash + 1;
    }
  }

  return base::StringPrintf("%s:%d: %s", file, line, message_without_prefix);
}

}  // namespace

#if BUILDFLAG(DCHECK_IS_CONFIGURABLE)
// In DCHECK-enabled Chrome builds, allow the meaning of LOGGING_DCHECK to be
// determined at run-time. We default it to INFO, to avoid it triggering
// crashes before the run-time has explicitly chosen the behaviour.
BASE_EXPORT logging::LogSeverity LOGGING_DCHECK = LOGGING_INFO;
#endif  // BUILDFLAG(DCHECK_IS_CONFIGURABLE)

// This is never instantiated, it's just used for EAT_STREAM_PARAMETERS to have
// an object of the correct type on the LHS of the unused part of the ternary
// operator.
std::ostream* g_swallow_stream;

bool BaseInitLoggingImpl(const LoggingSettings& settings) {
#if BUILDFLAG(IS_NACL)
  // Can log only to the system debug log and stderr.
  CHECK_EQ(settings.logging_dest & ~(LOG_TO_SYSTEM_DEBUG_LOG | LOG_TO_STDERR),
           0u);
#endif

#if BUILDFLAG(IS_CHROMEOS)
  g_log_format = settings.log_format;
#endif

#if BUILDFLAG(USE_RUNTIME_VLOG)
  MaybeInitializeVlogInfo();
#endif  // BUILDFLAG(USE_RUNTIME_VLOG)

#if !BUILDFLAG(USE_RUNTIME_VLOG) && DCHECK_IS_ON()
  MaybeWarnVmodule();
#endif  // !BUILDFLAG(USE_RUNTIME_VLOG) && DCHECK_IS_ON()

  g_logging_destination = settings.logging_dest;

#if BUILDFLAG(IS_FUCHSIA)
  if (g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) {
    GetScopedFxLogger() = base::ScopedFxLogger::CreateForProcess();
  }
#endif

  // ignore file options unless logging to file is set.
  if ((g_logging_destination & LOG_TO_FILE) == 0)
    return true;

#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  base::AutoLock guard(GetLoggingLock());
#endif

  // Calling InitLogging twice or after some log call has already opened the
  // default log file will re-initialize to the new options.
  CloseLogFileUnlocked();

#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (settings.log_file) {
    DCHECK(!settings.log_file_path);
    g_log_file = settings.log_file;
    return true;
  }
#endif

  DCHECK(settings.log_file_path) << "LOG_TO_FILE set but no log_file_path!";

  if (!g_log_file_name)
    g_log_file_name = new PathString();
  *g_log_file_name = settings.log_file_path;
  if (settings.delete_old == DELETE_OLD_LOG_FILE)
    DeleteFilePath(*g_log_file_name);

  return InitializeLogFileHandle();
}

void SetMinLogLevel(int level) {
  g_min_log_level = std::min(LOGGING_FATAL, level);
}

int GetMinLogLevel() {
  return g_min_log_level;
}

bool ShouldCreateLogMessage(int severity) {
  if (severity < g_min_log_level)
    return false;

  // Return true here unless we know ~LogMessage won't do anything.
  return g_logging_destination != LOG_NONE || g_log_message_handler ||
         severity >= kAlwaysPrintErrorLevel;
}

// Returns true when LOG_TO_STDERR flag is set, or |severity| is high.
// If |severity| is high then true will be returned when no log destinations are
// set, or only LOG_TO_FILE is set, since that is useful for local development
// and debugging.
bool ShouldLogToStderr(int severity) {
  if (g_logging_destination & LOG_TO_STDERR)
    return true;

#if BUILDFLAG(IS_FUCHSIA)
  // Fuchsia will persist data logged to stdio by a component, so do not emit
  // logs to stderr unless explicitly configured to do so.
  return false;
#else
  if (severity >= kAlwaysPrintErrorLevel)
    return (g_logging_destination & ~LOG_TO_FILE) == LOG_NONE;
  return false;
#endif
}

int GetVlogVerbosity() {
  return std::max(-1, LOG_INFO - GetMinLogLevel());
}

int GetVlogLevelHelper(const char* file, size_t N) {
  DCHECK_GT(N, 0U);

#if BUILDFLAG(USE_RUNTIME_VLOG)
  // Note: |g_vlog_info| may change on a different thread during startup
  // (but will always be valid or nullptr).
  VlogInfo* vlog_info = GetVlogInfo();
  return vlog_info ?
      vlog_info->GetVlogLevel(base::StringPiece(file, N - 1)) :
      GetVlogVerbosity();
#else
  return GetVlogVerbosity();
#endif  // BUILDFLAG(USE_RUNTIME_VLOG)
}

void SetLogItems(bool enable_process_id, bool enable_thread_id,
                 bool enable_timestamp, bool enable_tickcount) {
  g_log_process_id = enable_process_id;
  g_log_thread_id = enable_thread_id;
  g_log_timestamp = enable_timestamp;
  g_log_tickcount = enable_tickcount;
}

void SetLogPrefix(const char* prefix) {
  DCHECK(!prefix ||
         base::ContainsOnlyChars(prefix, "abcdefghijklmnopqrstuvwxyz"));
  g_log_prefix = prefix;
}

void SetShowErrorDialogs(bool enable_dialogs) {
  show_error_dialogs = enable_dialogs;
}

ScopedLogAssertHandler::ScopedLogAssertHandler(
    LogAssertHandlerFunction handler) {
  GetLogAssertHandlerStack().push(std::move(handler));
}

ScopedLogAssertHandler::~ScopedLogAssertHandler() {
  GetLogAssertHandlerStack().pop();
}

void SetLogMessageHandler(LogMessageHandlerFunction handler) {
  g_log_message_handler = handler;
}

LogMessageHandlerFunction GetLogMessageHandler() {
  return g_log_message_handler;
}

#if !defined(NDEBUG)
// Displays a message box to the user with the error message in it.
// Used for fatal messages, where we close the app simultaneously.
// This is for developers only; we don't use this in circumstances
// (like release builds) where users could see it, since users don't
// understand these messages anyway.
void DisplayDebugMessageInDialog(const std::string& str) {
  if (str.empty())
    return;

  if (!show_error_dialogs)
    return;

#if BUILDFLAG(IS_WIN)
  // We intentionally don't implement a dialog on other platforms.
  // You can just look at stderr.
  if (base::win::IsUser32AndGdi32Available()) {
    MessageBoxW(nullptr, base::as_wcstr(base::UTF8ToUTF16(str)), L"Fatal error",
                MB_OK | MB_ICONHAND | MB_TOPMOST);
  } else {
    OutputDebugStringW(base::as_wcstr(base::UTF8ToUTF16(str)));
  }
#endif  // BUILDFLAG(IS_WIN)
}
#endif  // !defined(NDEBUG)

LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
    : severity_(severity), file_(file), line_(line) {
  Init(file, line);
}

LogMessage::LogMessage(const char* file, int line, const char* condition)
    : severity_(LOGGING_FATAL), file_(file), line_(line) {
  Init(file, line);
  stream_ << "Check failed: " << condition << ". ";
}

LogMessage::~LogMessage() {
  size_t stack_start = stream_.str().length();
#if !defined(OFFICIAL_BUILD) && !BUILDFLAG(IS_NACL) && !defined(__UCLIBC__) && \
    !BUILDFLAG(IS_AIX)
  if (severity_ == LOGGING_FATAL && !base::debug::BeingDebugged()) {
    // Include a stack trace on a fatal, unless a debugger is attached.
    base::debug::StackTrace stack_trace;
    stream_ << std::endl;  // Newline to separate from log message.
    stack_trace.OutputToStream(&stream_);
    base::debug::TaskTrace task_trace;
    if (!task_trace.empty())
      task_trace.OutputToStream(&stream_);

    // Include the IPC context, if any.
    // TODO(chrisha): Integrate with symbolization once those tools exist!
    const auto* task = base::TaskAnnotator::CurrentTaskForThread();
    if (task && task->ipc_hash) {
      stream_ << "IPC message handler context: "
              << base::StringPrintf("0x%08X", task->ipc_hash) << std::endl;
    }

    // Include the crash keys, if any.
    base::debug::OutputCrashKeysToStream(stream_);
  }
#endif
  stream_ << std::endl;
  std::string str_newline(stream_.str());
  TRACE_LOG_MESSAGE(
      file_, base::StringPiece(str_newline).substr(message_start_), line_);

  if (severity_ == LOGGING_FATAL)
    SetLogFatalCrashKey(this);

  // Give any log message handler first dibs on the message.
  if (g_log_message_handler &&
      g_log_message_handler(severity_, file_, line_, message_start_,
                            str_newline)) {
    // The handler took care of it, no further processing.
    return;
  }

  if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) {
#if BUILDFLAG(IS_WIN)
    OutputDebugStringA(str_newline.c_str());
#elif BUILDFLAG(IS_APPLE)
    // In LOG_TO_SYSTEM_DEBUG_LOG mode, log messages are always written to
    // stderr. If stderr is /dev/null, also log via os_log. If there's something
    // weird about stderr, assume that log messages are going nowhere and log
    // via os_log too. Messages logged via os_log show up in Console.app.
    //
    // Programs started by launchd, as UI applications normally are, have had
    // stderr connected to /dev/null since OS X 10.8. Prior to that, stderr was
    // a pipe to launchd, which logged what it received (see log_redirect_fd in
    // 10.7.5 launchd-392.39/launchd/src/launchd_core_logic.c).
    //
    // Another alternative would be to determine whether stderr is a pipe to
    // launchd and avoid logging via os_log only in that case. See 10.7.5
    // CF-635.21/CFUtilities.c also_do_stderr(). This would result in logging to
    // both stderr and os_log even in tests, where it's undesirable to log to
    // the system log at all.
    const bool log_to_system = []() {
      struct stat stderr_stat;
      if (fstat(fileno(stderr), &stderr_stat) == -1) {
        return true;
      }
      if (!S_ISCHR(stderr_stat.st_mode)) {
        return false;
      }

      struct stat dev_null_stat;
      if (stat(_PATH_DEVNULL, &dev_null_stat) == -1) {
        return true;
      }

      return !S_ISCHR(dev_null_stat.st_mode) ||
             stderr_stat.st_rdev == dev_null_stat.st_rdev;
    }();

    if (log_to_system) {
      // Log roughly the same way that CFLog() and NSLog() would. See 10.10.5
      // CF-1153.18/CFUtilities.c __CFLogCString().
      CFBundleRef main_bundle = CFBundleGetMainBundle();
      CFStringRef main_bundle_id_cf =
          main_bundle ? CFBundleGetIdentifier(main_bundle) : nullptr;
      std::string main_bundle_id =
          main_bundle_id_cf ? base::SysCFStringRefToUTF8(main_bundle_id_cf)
                            : std::string("");

      const class OSLog {
       public:
        explicit OSLog(const char* subsystem)
            : os_log_(subsystem ? os_log_create(subsystem, "chromium_logging")
                                : OS_LOG_DEFAULT) {}
        OSLog(const OSLog&) = delete;
        OSLog& operator=(const OSLog&) = delete;
        ~OSLog() {
          if (os_log_ != OS_LOG_DEFAULT) {
            os_release(os_log_);
          }
        }
        os_log_t get() const { return os_log_; }

       private:
        os_log_t os_log_;
      } log(main_bundle_id.empty() ? nullptr : main_bundle_id.c_str());
      const os_log_type_t os_log_type = [](LogSeverity severity) {
        switch (severity) {
          case LOGGING_INFO:
            return OS_LOG_TYPE_INFO;
          case LOGGING_WARNING:
            return OS_LOG_TYPE_DEFAULT;
          case LOGGING_ERROR:
            return OS_LOG_TYPE_ERROR;
          case LOGGING_FATAL:
            return OS_LOG_TYPE_FAULT;
          case LOGGING_VERBOSE:
            return OS_LOG_TYPE_DEBUG;
          default:
            return OS_LOG_TYPE_DEFAULT;
        }
      }(severity_);
      os_log_with_type(log.get(), os_log_type, "%{public}s",
                       str_newline.c_str());
    }
#elif BUILDFLAG(IS_ANDROID)
    android_LogPriority priority =
        (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN;
    switch (severity_) {
      case LOGGING_INFO:
        priority = ANDROID_LOG_INFO;
        break;
      case LOGGING_WARNING:
        priority = ANDROID_LOG_WARN;
        break;
      case LOGGING_ERROR:
        priority = ANDROID_LOG_ERROR;
        break;
      case LOGGING_FATAL:
        priority = ANDROID_LOG_FATAL;
        break;
    }
    const char kAndroidLogTag[] = "chromium";
#if DCHECK_IS_ON()
    // Split the output by new lines to prevent the Android system from
    // truncating the log.
    std::vector<std::string> lines = base::SplitString(
        str_newline, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    // str_newline has an extra newline appended to it (at the top of this
    // function), so skip the last split element to avoid needlessly
    // logging an empty string.
    lines.pop_back();
    for (const auto& line : lines)
      __android_log_write(priority, kAndroidLogTag, line.c_str());
#else
    // The Android system may truncate the string if it's too long.
    __android_log_write(priority, kAndroidLogTag, str_newline.c_str());
#endif
#elif BUILDFLAG(IS_FUCHSIA)
    // LogMessage() will silently drop the message if the logger is not valid.
    // Skip the final character of |str_newline|, since LogMessage() will add
    // a newline.
    const auto message = base::StringPiece(str_newline).substr(message_start_);
    GetScopedFxLogger().LogMessage(file_, static_cast<uint32_t>(line_),
                                   message.substr(0, message.size() - 1),
                                   LogSeverityToFuchsiaLogSeverity(severity_));
#endif  // BUILDFLAG(IS_FUCHSIA)
  }

  if (ShouldLogToStderr(severity_)) {
    // Not using fwrite() here, as there are crashes on Windows when CRT calls
    // malloc() internally, triggering an OOM crash. This likely means that the
    // process is close to OOM, but at least get the proper error message out,
    // and give the caller a chance to free() up some resources. For instance if
    // the calling code is:
    //
    // allocate_something();
    // if (!TryToDoSomething()) {
    //   LOG(ERROR) << "Something went wrong";
    //   free_something();
    // }
    WriteToFd(STDERR_FILENO, str_newline.data(), str_newline.size());
  }

  if ((g_logging_destination & LOG_TO_FILE) != 0) {
    // We can have multiple threads and/or processes, so try to prevent them
    // from clobbering each other's writes.
    // If the client app did not call InitLogging, and the lock has not
    // been created do it now. We do this on demand, but if two threads try
    // to do this at the same time, there will be a race condition to create
    // the lock. This is why InitLogging should be called from the main
    // thread at the beginning of execution.
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
    base::AutoLock guard(GetLoggingLock());
#endif
    if (InitializeLogFileHandle()) {
#if BUILDFLAG(IS_WIN)
      DWORD num_written;
      WriteFile(g_log_file,
                static_cast<const void*>(str_newline.c_str()),
                static_cast<DWORD>(str_newline.length()),
                &num_written,
                nullptr);
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
      std::ignore =
          fwrite(str_newline.data(), str_newline.size(), 1, g_log_file);
      fflush(g_log_file);
#else
#error Unsupported platform
#endif
    }
  }

  if (severity_ == LOGGING_FATAL) {
    // Write the log message to the global activity tracker, if running.
    base::debug::GlobalActivityTracker* tracker =
        base::debug::GlobalActivityTracker::Get();
    if (tracker)
      tracker->RecordLogMessage(str_newline);

    char str_stack[1024];
    base::strlcpy(str_stack, str_newline.data(), std::size(str_stack));
    base::debug::Alias(&str_stack);

    if (!GetLogAssertHandlerStack().empty()) {
      LogAssertHandlerFunction log_assert_handler =
          GetLogAssertHandlerStack().top();

      if (log_assert_handler) {
        log_assert_handler.Run(
            file_, line_,
            base::StringPiece(str_newline.c_str() + message_start_,
                              stack_start - message_start_),
            base::StringPiece(str_newline.c_str() + stack_start));
      }
    } else {
      // Don't use the string with the newline, get a fresh version to send to
      // the debug message process. We also don't display assertions to the
      // user in release mode. The enduser can't do anything with this
      // information, and displaying message boxes when the application is
      // hosed can cause additional problems.
#ifndef NDEBUG
      if (!base::debug::BeingDebugged()) {
        // Displaying a dialog is unnecessary when debugging and can complicate
        // debugging.
        DisplayDebugMessageInDialog(stream_.str());
      }
#endif

      // Crash the process to generate a dump.
      IMMEDIATE_CRASH();
    }
  }
}

std::string LogMessage::BuildCrashString() const {
  return logging::BuildCrashString(file(), line(),
                                   str().c_str() + message_start_);
}

// writes the common header info to the stream
void LogMessage::Init(const char* file, int line) {
  base::StringPiece filename(file);
  size_t last_slash_pos = filename.find_last_of("\\/");
  if (last_slash_pos != base::StringPiece::npos)
    filename.remove_prefix(last_slash_pos + 1);

#if BUILDFLAG(IS_CHROMEOS)
  if (g_log_format == LogFormat::LOG_FORMAT_SYSLOG) {
    InitWithSyslogPrefix(
        filename, line, TickCount(), log_severity_name(severity_), g_log_prefix,
        g_log_process_id, g_log_thread_id, g_log_timestamp, g_log_tickcount);
  } else
#endif  // BUILDFLAG(IS_CHROMEOS)
  {
    // TODO(darin): It might be nice if the columns were fixed width.
    stream_ << '[';
    if (g_log_prefix)
      stream_ << g_log_prefix << ':';
    if (g_log_process_id)
      stream_ << base::GetUniqueIdForProcess() << ':';
    if (g_log_thread_id)
      stream_ << base::PlatformThread::CurrentId() << ':';
    if (g_log_timestamp) {
#if BUILDFLAG(IS_WIN)
      SYSTEMTIME local_time;
      GetLocalTime(&local_time);
      stream_ << std::setfill('0')
              << std::setw(2) << local_time.wMonth
              << std::setw(2) << local_time.wDay
              << '/'
              << std::setw(2) << local_time.wHour
              << std::setw(2) << local_time.wMinute
              << std::setw(2) << local_time.wSecond
              << '.'
              << std::setw(3) << local_time.wMilliseconds
              << ':';
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
      timeval tv;
      gettimeofday(&tv, nullptr);
      time_t t = tv.tv_sec;
      struct tm local_time;
      localtime_r(&t, &local_time);
      struct tm* tm_time = &local_time;
      stream_ << std::setfill('0')
              << std::setw(2) << 1 + tm_time->tm_mon
              << std::setw(2) << tm_time->tm_mday
              << '/'
              << std::setw(2) << tm_time->tm_hour
              << std::setw(2) << tm_time->tm_min
              << std::setw(2) << tm_time->tm_sec
              << '.'
              << std::setw(6) << tv.tv_usec
              << ':';
#else
#error Unsupported platform
#endif
    }
    if (g_log_tickcount)
      stream_ << TickCount() << ':';
    if (severity_ >= 0) {
      stream_ << log_severity_name(severity_);
    } else {
      stream_ << "VERBOSE" << -severity_;
    }
    stream_ << ":" << filename << "(" << line << ")] ";
  }
  message_start_ = stream_.str().length();
}

#if BUILDFLAG(IS_WIN)
// This has already been defined in the header, but defining it again as DWORD
// ensures that the type used in the header is equivalent to DWORD. If not,
// the redefinition is a compile error.
typedef DWORD SystemErrorCode;
#endif

SystemErrorCode GetLastSystemErrorCode() {
#if BUILDFLAG(IS_WIN)
  return ::GetLastError();
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  return errno;
#endif
}

BASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code) {
#if BUILDFLAG(IS_WIN)
  const int kErrorMessageBufferSize = 256;
  char msgbuf[kErrorMessageBufferSize];
  DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
  DWORD len = FormatMessageA(flags, nullptr, error_code, 0, msgbuf,
                             std::size(msgbuf), nullptr);
  if (len) {
    // Messages returned by system end with line breaks.
    return base::CollapseWhitespaceASCII(msgbuf, true) +
           base::StringPrintf(" (0x%lX)", error_code);
  }
  return base::StringPrintf("Error (0x%lX) while retrieving error. (0x%lX)",
                            GetLastError(), error_code);
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  return base::safe_strerror(error_code) +
         base::StringPrintf(" (%d)", error_code);
#endif  // BUILDFLAG(IS_WIN)
}

#if BUILDFLAG(IS_WIN)
Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file,
                                           int line,
                                           LogSeverity severity,
                                           SystemErrorCode err)
    : LogMessage(file, line, severity), err_(err) {}

Win32ErrorLogMessage::~Win32ErrorLogMessage() {
  stream() << ": " << SystemErrorCodeToString(err_);
  // We're about to crash (CHECK). Put |err_| on the stack (by placing it in a
  // field) and use Alias in hopes that it makes it into crash dumps.
  DWORD last_error = err_;
  base::debug::Alias(&last_error);
}
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
ErrnoLogMessage::ErrnoLogMessage(const char* file,
                                 int line,
                                 LogSeverity severity,
                                 SystemErrorCode err)
    : LogMessage(file, line, severity), err_(err) {}

ErrnoLogMessage::~ErrnoLogMessage() {
  stream() << ": " << SystemErrorCodeToString(err_);
  // We're about to crash (CHECK). Put |err_| on the stack (by placing it in a
  // field) and use Alias in hopes that it makes it into crash dumps.
  int last_error = err_;
  base::debug::Alias(&last_error);
}
#endif  // BUILDFLAG(IS_WIN)

void CloseLogFile() {
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  base::AutoLock guard(GetLoggingLock());
#endif
  CloseLogFileUnlocked();
}

#if BUILDFLAG(IS_CHROMEOS_ASH)
FILE* DuplicateLogFILE() {
  if ((g_logging_destination & LOG_TO_FILE) == 0 || !InitializeLogFileHandle())
    return nullptr;

  int log_fd = fileno(g_log_file);
  if (log_fd == -1)
    return nullptr;
  base::ScopedFD dup_fd(dup(log_fd));
  if (dup_fd == -1)
    return nullptr;
  FILE* duplicate = fdopen(dup_fd.get(), "a");
  if (!duplicate)
    return nullptr;
  std::ignore = dup_fd.release();
  return duplicate;
}
#endif

// Used for testing. Declared in test/scoped_logging_settings.h.
ScopedLoggingSettings::ScopedLoggingSettings()
    : min_log_level_(g_min_log_level),
      logging_destination_(g_logging_destination),
#if BUILDFLAG(IS_CHROMEOS)
      log_format_(g_log_format),
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
      enable_process_id_(g_log_process_id),
      enable_thread_id_(g_log_thread_id),
      enable_timestamp_(g_log_timestamp),
      enable_tickcount_(g_log_tickcount),
      log_prefix_(g_log_prefix),
      message_handler_(g_log_message_handler) {
  if (g_log_file_name)
    log_file_name_ = std::make_unique<PathString>(*g_log_file_name);
  // Duplicating |g_log_file| is complex & unnecessary for this test helpers'
  // use-cases, and so long as |g_log_file_name| is set, it will be re-opened
  // automatically anyway, when required, so just close the existing one.
  if (g_log_file) {
    CHECK(g_log_file_name) << "Un-named |log_file| is not supported.";
    CloseLogFileUnlocked();
  }
}

ScopedLoggingSettings::~ScopedLoggingSettings() {
  // Re-initialize logging via the normal path. This will clean up old file
  // name and handle state, including re-initializing the VLOG internal state.
  CHECK(InitLogging({
    .logging_dest = logging_destination_,
    .log_file_path = log_file_name_ ? log_file_name_->data() : nullptr,
#if BUILDFLAG(IS_CHROMEOS)
    .log_format = log_format_
#endif
  })) << "~ScopedLoggingSettings() failed to restore settings.";

  // Restore plain data settings.
  SetMinLogLevel(min_log_level_);
  SetLogItems(enable_process_id_, enable_thread_id_, enable_timestamp_,
              enable_tickcount_);
  SetLogPrefix(log_prefix_);
  SetLogMessageHandler(message_handler_);
}

#if BUILDFLAG(IS_CHROMEOS)
void ScopedLoggingSettings::SetLogFormat(LogFormat log_format) const {
  g_log_format = log_format;
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

void RawLog(int level, const char* message) {
  if (level >= g_min_log_level && message) {
    const size_t message_len = strlen(message);
    WriteToFd(STDERR_FILENO, message, message_len);

    if (message_len > 0 && message[message_len - 1] != '\n') {
      long rv;
      do {
        rv = HANDLE_EINTR(write(STDERR_FILENO, "\n", 1));
        if (rv < 0) {
          // Give up, nothing we can do now.
          break;
        }
      } while (rv != 1);
    }
  }

  if (level == LOGGING_FATAL)
    IMMEDIATE_CRASH();
}

// This was defined at the beginning of this file.
#undef write

#if BUILDFLAG(IS_WIN)
bool IsLoggingToFileEnabled() {
  return g_logging_destination & LOG_TO_FILE;
}

std::wstring GetLogFileFullPath() {
  if (g_log_file_name)
    return *g_log_file_name;
  return std::wstring();
}
#endif

#if !BUILDFLAG(USE_RUNTIME_VLOG)
int GetDisableAllVLogLevel() {
  return -1;
}
#endif  // !BUILDFLAG(USE_RUNTIME_VLOG)

// Used for testing. Declared in test/scoped_logging_settings.h.
ScopedVmoduleSwitches::ScopedVmoduleSwitches() = default;
#if BUILDFLAG(USE_RUNTIME_VLOG)
VlogInfo* ScopedVmoduleSwitches::CreateVlogInfoWithSwitches(
    const std::string& vmodule_switch) {
  // Try get a VlogInfo on which to base this.
  // First ensure that VLOG has been initialized.
  MaybeInitializeVlogInfo();

  // Getting this now and setting it later is racy, however if a
  // ScopedVmoduleSwitches is being used on multiple threads that requires
  // further coordination and avoids this race.
  VlogInfo* base_vlog_info = GetVlogInfo();
  if (!base_vlog_info) {
    // Base is |nullptr|, so just create it from scratch.
    return new VlogInfo(/*v_switch_=*/"", vmodule_switch, &g_min_log_level);
  }
  return base_vlog_info->WithSwitches(vmodule_switch);
}

void ScopedVmoduleSwitches::InitWithSwitches(
    const std::string& vmodule_switch) {
  // Make sure we are only initialized once.
  CHECK(!scoped_vlog_info_);
  {
#if defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
    // See comments on |g_vlog_info|.
    ScopedLeakSanitizerDisabler lsan_disabler;
#endif  // defined(LEAK_SANITIZER)
    scoped_vlog_info_ = CreateVlogInfoWithSwitches(vmodule_switch);
  }
  previous_vlog_info_ = ExchangeVlogInfo(scoped_vlog_info_);
}

ScopedVmoduleSwitches::~ScopedVmoduleSwitches() {
  VlogInfo* replaced_vlog_info = ExchangeVlogInfo(previous_vlog_info_);
  // Make sure something didn't replace our scoped VlogInfo while we weren't
  // looking.
  CHECK_EQ(replaced_vlog_info, scoped_vlog_info_);
}
#else
void ScopedVmoduleSwitches::InitWithSwitches(
    const std::string& vmodule_switch) {}

ScopedVmoduleSwitches::~ScopedVmoduleSwitches() = default;
#endif  // BUILDFLAG(USE_RUNTIME_VLOG)

}  // namespace logging

std::ostream& std::operator<<(std::ostream& out, const wchar_t* wstr) {
  return out << (wstr ? base::WStringPiece(wstr) : base::WStringPiece());
}

std::ostream& std::operator<<(std::ostream& out, const std::wstring& wstr) {
  return out << base::WStringPiece(wstr);
}

std::ostream& std::operator<<(std::ostream& out, const char16_t* str16) {
  return out << (str16 ? base::StringPiece16(str16) : base::StringPiece16());
}

std::ostream& std::operator<<(std::ostream& out, const std::u16string& str16) {
  return out << base::StringPiece16(str16);
}


text:
git add .
git reset -- *.bak
git status
git commit -m "%1"
git push gem5-stable.gh all


text:
rm -f test.sv/down
catexe test.sv/start <<EOF
#!/bin/sh
echo started
EOF

for code in 0 1 100
do
    echo "--- supervise restarts service exiting $code"
    catexe test.sv/run2 <<EOF
#!/bin/sh
echo rerunning
exec sleep 999
EOF
    catexe test.sv/run <<EOF
#!/bin/sh
echo running
mv run2 run
exit $code
EOF
    supervise test.sv &
    waituntil svup test.sv
    sleep 3
    svc -xk test.sv
    wait
    echo
done
rm -f test.sv/start


text:
package app.domain.dtos.workshops;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlValue;

@XmlRootElement(name = "paticipant")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class ParticipantDto {

	private String firstName;

	private String lastName;

	private String fullName;

	public ParticipantDto() {
		super();
	}

	@XmlTransient
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	@XmlTransient
	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@XmlValue
	public String getFullName() {
		return firstName + " " + lastName;
	}

	public void setFullName(String fullName) {
		this.fullName = fullName;
	}

}


text:
| Name | Unit | Dimensions |
|------|------|------------|
| Goal Abandonment Rate | % | Account, Property, Goal |
| Goal Completions | goals/h | Account, Property, Goal |
| Goal Conversion Rate | % | Account, Property, Goal |
| Goal Value | value/h | Account, Property, Goal |

### Google Analytics / Ecommerce metrics

| Name | Unit | Dimensions |
|------|------|------------|
| Average Order Value |  | Account, Property |
| Average QTY |  | Account, Property |
| Buy-to-Detail Rate | % | Account, Property |
| Cart-to-Detail Rate | % | Account, Property |
| Ecommerce Conversion Rate | % | Account, Property |
| Internal Promotion Clicks | clicks/h | Account, Property |
| Internal Promotion CTR | % | Account, Property |
| Internal Promotion Views | views/h | Account, Property |
| Per Session Value |  | Account, Property |
| Product List CTR | % | Account, Property |
| Product Revenue per Purchase |  | Account, Property |
| Refunds | refunds/h | Account, Property |
| Revenue per User |  | Account, Property |
| Total Value | value/h | Account, Property |
| Transactions | transactions/h | Account, Property |
| Transactions per User |  | Account, Property |

### Google Analytics / Global metrics

| Name | Unit | Dimensions |
|------|------|------------|
| Bounce rate | % | Account, Property |
| New sessions | % | Account, Property |
| Pages / Session |  | Account, Property |
| Pageviews | views/h | Account, Property |
| Session duration | s | Account, Property |
| Sessions | sessions/h | Account, Property |
| Users | users/h | Account, Property |