I am trying to use a logging mechanism as follows:
log_handler:
class: %monolog.handler.stream.class%
arguments: [ %kernel.logs_dir%/%kernel.environment%.yourFileName.log ]
logger:
class: %monolog.logger.class%
arguments: [ nameOfLoggingChannel ]
calls: [ [pushHandler, [#log_handler]] ]
however my app is crapping out parsing the "nameOfLoggingChannel". What is that? Can someone provide some guidance?
It's just a name. It will be included in the messages logged by that logger. Quoting from the docs:
Channels are a great way to identify to which part of the application a record is related. This is useful in big applications (and is leveraged by MonologBundle in Symfony2). You can then easily grep through log files for example to filter this or that type of log record.
Using different loggers with the same handlers allow to identify the logger that issued the record (through the channel name) by keeping the same handlers (for instance to use a single log file).
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler;
// Create some handlers
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
$firephp = new FirePHPHandler();
// Create the main logger of the app
$logger = new Logger('my_logger');
$logger->pushHandler($stream);
$logger->pushHandler($firephp);
// Create a logger for the security-related stuff with a different channel
$securityLogger = new Logger('security');
$securityLogger->pushHandler($stream);
$securityLogger->pushHandler($firephp);
Related
I am using the nexylan/slack Bundle for my symfony 3.4 application. I configured the slack Incoming WebHook for #general channel and it's working as expected. The bundle configuration looks something like:
nexy_slack:
# If you want to use an another httplug client service.
http:
client: httplug.client
# The Slack API Incoming WebHooks URL.
endpoint: https://hooks.slack.com/services/ABCD/987ABC
channel: null
username: null
icon: null
link_names: false
unfurl_links: false
unfurl_media: true
allow_markdown: true
markdown_in_attachments: []
Now I have another channel called #dev and I've added the Incoming WebHook and received the endpoint. I also want to send messages to the dev channel.
My question is, how can I configure the dev channel endpoint too in order to use it. Is there any way I can do this?
Here is the Slack Bundle
It looks like the bundle only supports 1 endpoint. If you want to have multiple endpoints you either have to fork or send in a PR.
Basically what you need to do, is adjust both files in src/DependencyInjection.
In Configuration.php you need to ensure that you can define multiple endpoints by adding a parent array node, e.g. called endpoints. Then inside NexySlackExtension you can foreach through each endpoint configuration and do the same configuration as before just add a prefix or suffix. So something like:
$configuration = new Configuration();
$endpointConfigs = $this->processConfiguration($configuration, $configs);
foreach ($endpointConfigs['endpoints'] as $config) {
// ....
}
You might also want do add some special handling for a "default" endpoint. This should already do the trick, although it might need some adjustments as I haven't looked into the Bundle in detail. Maybe you can also contact the author via a ticket in the Issue tracker and they can help you write a PR.
I want to have a list of services and class names in my web application. I can use this command in console:
php bin/console debug:container
And I get something like this:
Symfony Container Public Services
=================================
-------------------------------------------------------------------- --------------------------------------------------------------------------------------------
Service ID Class name
-------------------------------------------------------------------- --------------------------------------------------------------------------------------------
annotation_reader Doctrine\Common\Annotations\CachedReader
app.annotations.softdelete.driver AppBundle\Doctrine\SoftDelete\Mapping\Driver\Annotation
app.annotations.translate.driver AppBundle\Doctrine\Mapping\Driver\TranslateDriver
app.be_auth_controller.listener AppBundle\EventListener\BeAuthControllerListener
I want to have this information on a web page using Symfony 3.
I created a service and I used:
$this->container->getServiceIds();
which returns something like:
[
0 => "service_container"
1 => "annotation_reader"
2 => "annotations.reader"
3 => "app.annotations.softdelete.driver"
4 => "app.annotations.translate.driver"
...
]
I don't know, how to get the class names.
In any cases works this:
get_class($this->container->get($this->container->getServiceIds()[1]))
But in some other cases it throws different exceptions.
To get full definition of given service you can use ContainerBuilder and Symfony cache file.
first create instance of ContainerBuilder:
$container = new ContainerBuilder();
then load cache file:
$cachedFile = $this->container->getParameter('debug.container.dump');
$loader = new XmlFileLoader($container, new FileLocator());
$loader->load($cachedFile);
now you can get full definition of your service like this:
$definition = $container->getDefinition('service_name')
$definition->getClass();
Your attempt with get_class is what came to mind as I was reading it, but whatever errors you are getting will come from improper fetching of those services. After all when you call $container->get(...), its at that moment instantiating those classes.
To be honest the output you are looking to replicate can be reproduced based on the method used by that command.
https://github.com/symfony/framework-bundle/blob/master/Command/ContainerDebugCommand.php
You'll just need to adapt it to work for you.
So Laravel 5 was finally released yesterday with the final implementation of the command bus but I was wandering, what's the real difference in using a command bus over event mechanisms that we have in the previous releases?
Ok, I see the reason that it can be used to create commands from Request objects which is pretty useful but beyond that it seems to behave in a similar way even down to the whole queuing functionality for events now?
Can you please provide examples of use cases and where the pros and cons of either are?
Commands are things about to happen right now. i.e. "CreateUser"
Events are things that have just occured right now - i.e. "UserSuccessfullyCreated"
The differences appear minor - but have some key differences.
Commands must be specifically called/dispatched. I.e. if you want to
do CommandX - you must call CommandX somewhere.
Events respond to an event firing anywhere in your application.
The great thing is multiple event handling classes can respond to the
same event.
Lets do an example to illustrate it best. Lets say we create a user, and we want to send them a welcome email and also update our newsletter list.
In a Command Scenario would would do
AdminController {
function create() {
Bus::dispatch(new CreateUser(Auth::user());
}
}
then in our CommandClass - we would do
public function handle(CreateUser $auth)
{
// 1. Create the user here
// 2. Send welcome email
// 3. Update our newsletter
}
But if we use events - we would do something like this in our CommandClass
public function handle(CreateUser $auth)
{
// 1. Create the user here
Event::fire(new UserWasCreated($user));
}
then we can create as many events as we want to listen to that event and do something:
EventClassA
Event::listen('UserWasCreated', function($event)
{
// 2. Send welcome email
});
EventClassB
Event::listen('UserWasCreated', function($event)
{
// 3. Update our newsletter
});
The great thing is separation of concerns. The command "createuser" now does not need to worry itself about what happens after a user is created. It just needs to CreateUser.
Also - if we want to add another function after a user signs up - say enter them in a lotto draw - you can just add another Event Class and add a new event listener.
EventClassC
Event::listen('UserWasCreated', function($event)
{
// 4. Register them in lotto
});
Notice how we didnt need to touch the command CreateUser class code at all? This provides a true separation concerns of classes in a OOP style approach.
I just want to share my understanding of this concept on top of the correct answer:
The main difference is that Commands can change a Model state, while Events just react to a state change.
COMMANDS:
Commands in Laravel represent the implementation of the Command design pattern.
The main adventages of Commands:
The can be accessed from anywhere
They are very easy to read by any other developer
To create a Command in Laravel 5:
You need to generate a command DTO (which can implement the SelfHandling interface). Using php artisan make:command {command-name}
Example: php artisan make:command Course/PostCourseCommand
The naming convention for commands: speak the business language and add postfix Command to it
To call (dispatch) the command from you controller, you can use:
$this->dispatch(new PostCourseCommand())
or
Bus::dispatch(new PostCourseCommand());
Side Note:
The "dispatch from request” feature is a nice way to skip passing the variables to the command constructor one by one, instead it will resolve this for you:
Example:
$test_request = Request::create('/test', 'GET', [
'name' => 'Mahmoud',
'nickname' => 'Mega'
]);
$result = Bus::dispatchFrom(
CreateCourse::class, $test_request
);
Finally:
You can separate the handler function and it’s logic from the command DTO to the Handlers directory, to do so:
Generate a command handler via artisan
art handler:command --command="Course/PoatCourseCommand"
remove the SelfHandling interface from the Command class so it will search for a handler to handle it.
EVENTS:
Events in Laravel represent the implementation of the Observer design pattern.
To create an Event in Laravel 5:
use artisan: art make:event {event-name}
Example: art make:event LogSomething
generate an event handler for that event
art handler:event LogSomething --event="LogSomething"
register the event and it’s handler in the event service provider (app/Providers/EventServiceProvider.php)
Example:
protected $listen = [
\Zzz\Events\LogSomething::class => [ // event.name
\Zzz\Handlers\Events\LogSomething::class, //EventListener
],
],
To call (fire) an Event:
use:
Event::fire(New LogSomething());
or you can use the event helper
event(New LogSomething());
Side Note:
alternatively you can generate an event by simply registering the event in the service provider then running this command.
php artisan event:generate << this will automatically add the two classes for you
Also you can listen to an event without creating an event handler or registering a lister in the listeners array, by just going to the event service prover and inside the boot function writing your event and its action (NOT RECOMMENDED). Example:
Event::listen('XXX\Events\DoSomethingElse', function($event)
{
dd('handle me :)');
});
Finally: you can queue an event or even subscribe to multiple events from within the class itself..
I've heard a lot about monolog(https://github.com/Seldaek/monolog) & trying to use that in one of our app. But, can't able to fig. out how to use that. Don't know it's I'm only can't able to get any documentation of it or really it has no documentation at all.
We want to log all our errors in DB & as well as send an email notification about error when it'll get generate. For sending email we are using Swiftmailer(swiftmailer.org).
I can be able to run this sample code from Github link,
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
// add records to the log
$log->addWarning('Foo');
$log->addError('Bar');
but can't able to understand how to use this with DB & any other email library.
You posted an example yourself. Instead of StreamHandler use one or more of the other handlers that monolog is offering.
You have to look into the code of the handlers to see which dependencies they need. Look inside the Monolog directory and you'll find the Handler classes. Code is the most reliable documentation.
<?php
use Monolog\Logger;
use Monolog\Handler\SwiftMailerHandler;
use Swift_Mailer;
// ... more dependencies you need
// create your Swift_Mailer and Swift_Message instances
$handlers = [
new SwiftMailerHandler($swiftMailer, $swiftMessage),
// add more handler you need
];
$log = new Logger('name', $handlers);
$log->warning('Foo');
$log->error('Bar');
You have to create a Swift_Mailer and Swift_Message instance for the SwiftMailerHandler. Instead of pushHandler, you can add an array of handlers into the Logger constructor.
The Swift_Message instance is used for every log message where the message replaces every time the mail body.
I can only suggest to you to read the monolog code for information where a further documentation is missing.
I would like to use Doctrine (v2.4) in my ZendFramework (v1.11) application, which I am starting from scratch. There are some articles describing such integration, but they seem quite complicated and a little out of date. Is there any fairly simple way to connect ZF1 and Doctrine2?
I've implemented this as an application resource (extending \Zend_Application_Resource_ResourceAbstract)
The code is quite long so below is a top level check list of the requirements.
Create a doctrine entity manager configuration instance (Doctrine\ORM\Configuration).
$config = new Doctrine\ORM\Configuration();
Populate the configuration with the required data (metadata driver, cache config etc). Doctrine's documentation is a good reference here to what would be required (http://docs.doctrine-project.org/en/latest/reference/configuration.html)
Example here uses the Annotation driver:
$driver = new Driver\AnnotationDriver(
new Annotations\CachedReader(new Annotations\AnnotationReader(), new Cache\ArrayCache()),
$entityDirs
);
$config->setMetadataDriverImpl($driver);
Lastly pass this new config instance to the static entity manager EntityManager::create
E.G. ($options here is the database connection info as exampled in the above link)
$entityManager = EntityManager::create($options['database'], $config);
Take a look at my full source, at the very least it will give you a head start:
https://github.com/alex-patterson-webdev/Multiverse/blob/master/lib/Multiverse/Application/Resource/Entitymanager.php