# Customizing Clients

## Logger injection

As the `Rackspace` client extends the `OpenStack` client, they both support passing `$options` as an array via the constructor’s third parameter. The options are passed as a config to the Guzzle client, but also allow to inject your own logger.

Your logger should implement the `Psr\Log\LoggerInterface` as defined in PSR-3. One example of a compatible logger is Monolog. When the client does create a service, it will inject the logger if one is available.

To inject a `LoggerInterface` compatible logger into a new client:

    use Monolog\Logger;
    use OpenCloud\OpenStack;

    // create a log channel
    $logger = new Logger('name');

    $client = new OpenStack('http://identity.my-openstack.com/v2.0', array(
      'username' => 'foo',
      'password' => 'bar'
    ), array(
      'logger' => $logger,
    ));

## Authentication

The client does not automatically authenticate against the API when it is instantiated - it waits for an API call. When this happens, it checks whether the current “token” has expired, and (re-)authenticates if necessary.

You can force authentication, by calling:

    $client->authenticate();

If the credentials are incorrect, a `401` error will be returned. If credentials are correct, a `200` status is returned with your Service Catalog.

## Service Catalog

The Service Catalog is returned on successful authentication, and is composed of all the different API services available to the current tenant. All of this functionality is encapsulated in the `Catalog` object, which allows you greater control and interactivity.

    /** @var OpenCloud\Common\Service\Catalog */
    $catalog = $client->getCatalog();

    // Return a list of OpenCloud\Common\Service\CatalogItem objects
    foreach ($catalog->getItems() as $catalogItem) {

        $name = $catalogItem->getName();
        $type = $catalogItem->getType();

        if ($name == 'cloudServersOpenStack' && $type == 'compute') {
            break;
        }

        // Array of OpenCloud\Common\Service\Endpoint objects
        $endpoints = $catalogItem->getEndpoints();
        foreach ($endpoints as $endpoint) {
            if ($endpoint->getRegion() == 'DFW') {
                echo $endpoint->getPublicUrl();
            }
        }
    }

As you can see, you have access to each Service’s name, type and list of endpoints. Each endpoint provides access to the specific region, along with its public and private endpoint URLs.

## Default HTTP headers

To set default HTTP headers:

    $client->setDefaultOption('headers/X-Custom-Header', 'FooBar');

## User agents

php-opencloud will send a default `User-Agent` header for every HTTP request, unless a custom value is provided by the end-user. The default header will be in this format:

> User-Agent: OpenCloud/xxx cURL/yyy PHP/zzz

where `xxx` is the current version of the SDK, `yyy` is the current version of cURL, and `zzz` is the current PHP version. To override this default, you must run:

    $client->setUserAgent('MyCustomUserAgent');

which will result in:

> User-Agent: MyCustomUserAgent

If you want to set a prefix for the user agent, but retain the default `User-Agent` as a suffix, you must run:

    $client->setUserAgent('MyPrefix', true);

which will result in:

> User-Agent: MyPrefix OpenCloud/xxx cURL/yyy PHP/zzz

where `$client` is an instance of `OpenCloud\OpenStack` or `OpenCloud\Rackspace`.

## Other functionality

For a full list of functionality provided by Guzzle, please consult the official documentation.