New Features for Querying Polymorphic Relations in Laravel 5.8.27
The Laravel team released v5.8.27 with a whereHasMorph() method to work with polymorphic Eloquent relationships (MorphTo).
The new whereHasMorph() and corresponding methods make it possible to query polymorphic relationships with something like the following:
Comment::whereHasMorph('commentable', [Post::class, Video::class], function ($query) { $query->where('title', 'foo'); })->get();
Which produces something like the following query:
select * from "comments" where ( ( "commentable_type" = 'App\Post' and exists ( select * from "posts" where "comments"."commentable_id" = "posts"."id" and "title" = 'foo' ) ) or ( "commentable_type" = 'App\Video' and exists ( select * from "videos" where "comments"."commentable_id" = "videos"."id" and "title" = 'foo' ) ) )
All the examples shown here are from the pull request (#28928) description, which explains it in further detail, so check out the full notes:
By creating a temporary BelongsTo relationship for each type and allowing relationship instances as the first argument of has(), we can reuse most of the existing code.
The type is passed as the second argument to the closure, which simplifies queries with different constraints:
Comment::whereHasMorph('commentable', [Post::class, Video::class], function ($query, $type) { if ($type === Post::class) { // $query-> } if ($type === Video::class) { // $query-> } });
Last, providing a wildcard as the second argument will let Laravel get the possible types from the database:
Comment::whereHasMorph('commentable', '*', function ($query) { $query->where('title', 'foo'); })->get();
Next, the mix asset URL is configurable via the MIX_ASSET_URL environment variable.
Next, you can set the RedisManager default driver with the setDriver() method.
You can see the full list of fixes below, and the whole diff between 5.8.26 and 5.8.27 on GitHub. The full release notes for Laravel 5.8 are available in the GitHub 5.8 changelog:
There are over one million Dockerfiles on GitHub today, but not all Dockerfiles are created equally. Efficiency is critical, and this blog series will cover five areas for Dockerfile best practices to help you write better Dockerfiles: incremental build time, image size, maintainability, security and repeatability. If you’re just beginning with Docker, this first blog post is for you! The next posts in the series will be more advanced.
Important note:the tips below follow the journey of ever-improving Dockerfiles for an example Java project based on Maven. The last Dockerfile is thus the recommended Dockerfile, while all intermediate ones are there only to illustrate specific best practices.
Incremental build time
In a development cycle, when building a Docker image, making code changes, then rebuilding, it is important to leverage caching. Caching helps to avoid running build steps again when they don’t need to.
Tip #1: Order matters for caching
However, the order of the build steps (Dockerfile instructions) matters, because when a step’s cache is invalidated by changing files or modifying lines in the Dockerfile, subsequent steps of their cache will break. Order your steps from least to most frequently changing steps to optimize caching.
Tip #2: More specific COPY to limit cache busts
Only copy what’s needed. If possible, avoid “COPY .” When copying files into your image, make sure you are very specific about what you want to copy. Any changes to the files being copied will break the cache. In the example above, only the pre-built jar application is needed inside the image, so only copy that. That way unrelated file changes will not affect the cache.
Tip #3: Identify cacheable units such as apt-get update & install
Each RUN instruction can be seen as a cacheable unit of execution. Too many of them can be unnecessary, while chaining all commands into one RUN instruction can bust the cache easily, hurting the development cycle. When installing packages from package managers, you always want to update the index and install packages in the same RUN: they form together one cacheable unit. Otherwise you risk installing outdated packages.
Reduce Image size
Image size can be important because smaller images equal faster deployments and a smaller attack surface.
Tip #4: Remove unnecessary dependencies
Remove unnecessary dependencies and do not install debugging tools. If needed debugging tools can always be installed later. Certain package managers such as apt, automatically install packages that are recommended by the user-specified package, unnecessarily increasing the footprint. Apt has the –no-install-recommends flag which ensures that dependencies that were not actually needed are not installed. If they are needed, add them explicitly.
Tip #5: Remove package manager cache
Package managers maintain their own cache which may end up in the image. One way to deal with it is to remove the cache in the same RUN instruction that installed packages. Removing it in another RUN instruction would not reduce the image size.
There are further ways to reduce image size such as multi-stage builds which will be covered at the end of this blog post. The next set of best practices will look at how we can optimize for maintainability, security, and repeatability of the Dockerfile.
Maintainability
Tip #6: Use official images when possible
Official images can save a lot of time spent on maintenance because all the installation stamps are done and best practices are applied. If you have multiple projects, they can share those layers because they use exactly the same base image.
Tip #7: Use more specific tags
Do not use the latest tag. It has the convenience of always being available for official images on Docker Hub but there can be breaking changes over time. Depending on how far apart in time you rebuild the Dockerfile without cache, you may have failing builds.
Instead, use more specific tags for your base images. In this case, we’re using openjdk. There are a lot more tags available so check out the Docker Hub documentation for that image which lists all the existing variants.
Tip #8: Look for minimal flavors
Some of those tags have minimal flavors which means they are even smaller images. The slim variant is based on a stripped down Debian, while the alpine variant is based on the even smaller Alpine Linux distribution image. A notable difference is that debian still uses GNU libc while alpine uses musl libc which, although much smaller, may in some cases cause compatibility issues. In the case of openjdk, the jre flavor only contains the java runtime, not the sdk; this also drastically reduces the image size.
Reproducibility
So far the Dockerfiles above have assumed that your jar artifact was built on the host. This is not ideal because you lose the benefits of the consistent environment provided by containers. For instance if your Java application depends on specific libraries it may introduce unwelcome inconsistencies depending on which computer the application is built.
Tip #9: Build from source in a consistent environment
The source code is the source of truth from which you want to build a Docker image. The Dockerfile is simply the blueprint.
You should start by identifying all that’s needed to build your application. Our simple Java application requires Maven and the JDK, so let’s base our Dockerfile off of a specific minimal official maven image from Docker Hub, that includes the JDK. If you needed to install more dependencies, you could do so in a RUN step.
The pom.xml and src folders are copied in as they are needed for the final RUN step that produces the app.jar application with mvn package. (The -e flag is to show errors and -B to run in non-interactive aka “batch” mode).
We solved the inconsistent environment problem, but introduced another one: every time the code is changed, all the dependencies described in pom.xml are fetched. Hence the next tip.
Tip #10: Fetch dependencies in a separate step
By again thinking in terms of cacheable units of execution, we can decide that fetching dependencies is a separate cacheable unit that only needs to depend on changes to pom.xml and not the source code. The RUN step between the two COPY steps tells Maven to only fetch the dependencies.
There is one more problem that got introduced by building in consistent environments: our image is way bigger than before because it includes all the build-time dependencies that are not needed at runtime.
Tip #11: Use multi-stage builds to remove build dependencies (recommended Dockerfile)
Multi-stage builds are recognizable by the multiple FROM statements. Each FROM starts a new stage. They can be named with the AS keyword which we use to name our first stage “builder” to be referenced later. It will include all our build dependencies in a consistent environment.
The second stage is our final stage which will result in the final image. It will include the strict necessary for the runtime, in this case a minimal JRE (Java Runtime) based on Alpine. The intermediary builder stage will be cached but not present in the final image. In order to get build artifacts into our final image, use COPY --from=STAGE_NAME. In this case, STAGE_NAME is builder.
Multi-stage builds is the go-to solution to remove build-time dependencies.
We went from building bloated images inconsistently to building minimal images in a consistent environment while being cache-friendly. In the next blog post, we will dive more into other uses of multi-stage builds.
New blog from #Docker: Intro guide to Dockerfile best practices Click To Tweet
The main feature of the package is that you don’t have to make any changes to your app’s code. After it identifies the tenant using the hostname, it automatically configures database, Redis, cache and the filesystem for that tenant.
This tutorial explains the basics of making an app multi-tenant using this package. For a real-world production application, you should read the documentation. It’s not long.
Installing the tenancy package
The package supports Laravel 5.7 and 5.8.
You will also need Redis and phpredis.
composer require stancl/tenancy
Adding middleware
Open app/Http/Kernel.php and make the Stancl\Tenancy\Middleware\InitializeTenancy middleware top priority, to make sure everything is configured for tenancy before any code is run.
The package lets you have tenant routes in routes/tenant.php and shared routes in routes/web.php. When someone visits a tenant route, the InitializeMiddleware will configure everything for tenancy. If you have some content you don’t want to apply tenany for, such as landing pages, sign up pages, etc, put those into web.php.
Since we don’t have any shared content, we’ll just rename routes/web.php to routes/tenant.php and create an empty routes/web.php file.
Configuration
First you need to publish the configuration file of the package. Run
and you should see something along the lines of Copied File [...] to [/config/tenancy.php].
This lets us make changes to the configuration file of the tenancy package. I don’t want to use MySQL for this simple repository, so I will change the DB driver for the application in .env and for the package in config/tenancy.php:
By default, the package uses Redis as the "central" storage — for storing data about tenants. Redis is ideal for this thanks to its high performance. You don’t really need to use a relational database for this.
Make sure you use a unique database number — Redis supports 16 databases which let you have multiple applications use the same Redis instance without any conflicts.
Creating tenants
We’ll create two tenants to see that the data separation works correctly. We’ll be using php artisan tinker to keep it simple. For your app, you should create a page that does this.
We’ll use these two subdomains:
tenant1.localhost
tenant2.localhost
Anything under the .localhost TLD is automatically redirected to 127.0.0.1, so we don’t have to make any changes to /etc/hosts.
Open php artisan tinker and run these two functions:
Note: If you’re using the same sample blog repository as I chose, you might have to tweak the 2017_03_04_133429_add_columns_to_user migration (make the API key nullable). This is not an issue with the tenancy package but with the blog repository. I have submitted a PR so by the time you’re reading this, this should no longer be an issue.
I didn’t want to set up Apache or Nginx just for a simple demonstration, so I used:
php artisan serve
Now we can visit the sites. If we visit tenant1.localhost:8000 and tenant2.localhost:8000, we can see two same applications, running from the same source code, but with different content.
First blog
Second blog
Closing
My package makes it very easy to implement multi-tenancy into any Laravel application in a way that the application code doesn’t have to be aware of any tenancy. The magic is automatically identifying tenants based on the subdomain when a route in the routes/tenant.php file is visited (those routes have the InitializeTenancy middleware applied on them) and then accordingly switching the database and Redis connections and making some changes to the cache and filesystem.
If you’re building a multi-tenant app, I highly recommend using this package. Implementing tenancy on your own can be painful, which is why I created this package — any Laravel application I make can be made multi-tenant in 5 minutes using this package.
Thanks for reading. If you have any questions or suggestions about the package, feel free to open Issues on the GitHub page.
“Did anyone pack my pill case?”Image: Sony (YouTube)
Trailer FrenzyA special place to find the newest trailers for movies and TV shows you’re craving.
If you thought Dwayne Johnson channeling a teenage boy in the video game version of “Jumaaanjee,” you ain’t seen nothing yet. Check out the first trailer for Jumanji: The Next Level.
Jumanji: The Next Level is the sequel to the surprise hit Jumanji: Welcome to the Jungle and the story picks up some time after the events of the previous movie, when four teenagers ended up in the bodies of video game avatars (played by Johnson, Kevin Hart, Karen Gillan, and Jack Black), forced to play the game to get out alive.
Spencer (Alex Wolff) has seemingly gone missing inside the now-malfunctioning video game, and it’s up to his three friends to go in after him. Once our heroes step inside, they quickly realize something’s wrong. Bethany’s nowhere to be found, characters are switching places…and two old guys have shown up! That’s right, Danny DeVito and Danny Glover are playing the game too. DeVito’s character is in Johnson’s avatar, and Hart is channeling Glover.
I will say: Watching Johnson and Hart play two old guys is more of a delight than I anticipated. Johnson’s got that Nor’Easter accent down. However, it’ll be sad not seeing Black perfectly channeling Bethany, as Fridge (Ser’Darius Blain) is now in his body.
Jumanji: The Next Level sees the return of Nick Jonas, Madison Iseman, and Morgan Turner, along with a new character played by Awkwafina. The movie debuts on December 13.
For more, make sure you’re following us on our new Instagram @io9dotcom.
Polk County, FL — County Sheriff Grady Judd is a peace officer who knows and appreciates the value of armed citizens. In this short video, he encourages people to get guns and become good at using them.
If you’re not afraid of a gun, get one. Become proficient. Get a concealed firearms license and carry it.
And if you need to shoot somebody, shoot ’em a lot.
He also notes that “the armed assailant doesn’t plan on you fighting back. He plans on having a gun, doing all the shooting, and you’re just the sitting duck.”
Well the ducks need to shoot back.
Good advice. It worked for the guy who was attacked at a gas pump last month. He put one bad guy in the hospital and walked away. Don’t you just love a happy ending?
Sheriff Judd says everyone needs to prepare for an active shooter. If you’re comfortable with a gun, arm yourself, he says. "And if you need to shoot somebody, shoot ’em a lot." MORE: fox13news.com/news/local-news/262968643-story
USA – -(AmmoLand.com)- When most Americans think of espionage, we think of debonair foreign spies sneaking around military compounds – or bespectacled hackers hammering away at keyboards to steal top secret information from foreign adversaries.
But there is an entire world of espionage happening right under our noses – at American colleges and universities.
Foreign intelligence services routinely probe computer systems at US higher education institutions – and they also enlist (or implant) students and professors as assets to pass important research and findings to their spy agencies.
The main goal isn’t typically to learn any classified state secrets (not in academic espionage anyway). Foreign actors want to steal the important technological advancements, research, and innovations being created by our nation’s best and brightest researchers and scientists.
Back in 2013, the Commission on the Theft of Intellectual Property said that this academic espionage made up a significant part of the estimated $300 billion of intellectual property theft America endured that year. According to the commission, “American scientific innovations and new technologies are tracked and stolen from American universities, national laboratories, private think tanks, and start-up companies, as well as from the major R&D centers of multinational companies.”
This is a serious problem for the United States. If this level of academic espionage continues, our ability to lead the world in innovation and new technology could be severely hampered – and the future could be defined by the countries who are stealing our ideas.
One of the biggest offenders is China. I detail the many ways in which the Chinese Communist Party is spying on Americans (and the Chinese people) in my new book Trump vs. China: America’s Greatest Challenge, which comes out in October. Former National Counterintelligence Executive Michelle Van Cleave told the US-China Economic and Security Review Commission on June 9, 2016 that “hundreds of thousands of students and academicians” aid China’s spy operations. Many of these students, professors, and researchers (either willingly or through intense pressure and coercion from the Chinese Communist Party) help to “potentially extend the reach of Chinese intelligence into the core structures of our nation’s security,” Van Cleave told the commission.
Of particular concern are China’s Confucius Institutes that have been established on campuses in the US and across the world. At first blush, these institutes appear to be legitimate academic foreign exchange programs promoting Chinese language and cultural studies. However, they are also used to spread Chinese Communist Party propaganda and soft power by promoting the party’s vision of China. Concerns have been raised that they could be used for espionage efforts. On February 13, 2018, FBI Director Christopher Wray told the Senate Intelligence Committee that China is beginning to pull back on this effort, but the institutes are still “something that we’re watching warily and in certain instances have developed … appropriate investigative steps.”
Luckily, there is an ongoing effort in Congress to curb this activity and protect American colleges and universities from being helpless targets of foreign espionage.
The Stop Higher Education Espionage and Theft Act of 2019 (or SHEET Act) was introduced in the Senate by Senator Ted Cruz of Texas. It is being carried in the US House of Representatives by Florida Representative Francis Rooney.
This bill will create a new way for federal law enforcement to designate an entity suspected of spying in our colleges and universities as a “foreign intelligence threat to higher education.” (The designation will be promptly appealable when warranted.) Colleges and universities that accept gifts from or enter into contracts with designated threats will have more stringent reporting requirements under the Higher Education Act. If evidence of espionage is found, US authorities will be able to quickly remove identified threats.
This is a critically important problem that we must solve. When foreign countries steal our research and ideas, American researchers, innovators, and thinkers lose the ability to lead our country into the future. Ultimately, this costs American jobs – and our security.
Congress should pass the SHEET Act as soon as possible.
Your Friend, Newt
Newt’s World Ep 21: Communist China vs. Hong Kong
One of the most important struggles on the planet is taking place right now between the people of Hong Kong and Communist China. In this week’s episode of my Newt’s World podcast, I discuss the implications of this major turning point in China and across the world. Listen for free here>>
Newt Gingrich is well-known as the architect of the “Contract with America” that led the Republican Party to victory in 1994 by capturing the majority in the U.S. House of Representatives for the first time in forty years. After he was elected Speaker, he disrupted the status quo by moving power out of Washington and back to the American people.
Gingrich Productions is a performance and production company featuring the work of Newt Gingrich and Callista Gingrich. Visit : www.gingrichproductions.com
Unless you’ve been living under a rock, you’ll know that SIG SAUER has upped the ante in the concealed carry and self-defense world with their P365. For the cave dwellers among you, the P365 — SIG calls it “America’s most popular handgun” — is a sub-compact 9mm pistol that boasts excellent accuracy and a staggering 10+1 standard capacity in a very compact form factor.
Recently they raised the bar by making their already innovative pistol safer in the eyes of many people, this writer included.
The P365 variant here, announced at this year’s SHOT Show, features a manual thumb safety. That may not seem like that much of a big deal until you realize that a manual safety is a make or break option for many, many shooters. I conducted an informal survey among several dozen people I encountered in the course of my daily travels and about two-thirds of the crowd wanted an external safety.
Tactical polo bros rarely value a manual safety and sometimes consider it to be a dangerous feature or an outright liability. This high-speed mentality often ignores the fact that the majority of people who carry aren’t gun people and want simple, safe features that they are comfortable with.
I won’t get into the nuances of this mentality as I could never consume enough Monster Energy flavored vape cartridges to put myself into the mindset necessary to relay it to you.
Suffice to say, even routine actions like loading and holstering can lead to an accidental discharge or an unsafe situation when no manual safety is present. The fact that the gun is basically ready to fire the moment you put your hand on the grip is not something that delights many people, especially those who carry off-body in a purse, backpack, or diaper bag.
The addition of a manual safety model to the P365 line is the thing that fully convinced me to make this a daily use carry gun. I previously reviewed the original P365 and liked it, but I never really felt great about carrying it. The triggers on the P365 pistols I have tested are light and crisp, just like a full-size pistol.
The small grip and crisp trigger made it so that I was somewhat uncomfortable with carrying it for fear of an accidental discharge. The addition of a manual safety makes me completely comfortable with it now in both a pocket holster or IWB.
Josh Wayner for TTAG
I have carried a Smith & Wesson .38 J-Frame for years and it has no manual safety. It also has a super-heavy double action trigger that really can’t be pulled by accident.
The SIG P365 has a trigger pull that’s significantly lighter at about 7 lbs, which puts it in the same range as most regular 1911s and some AR rifles. That’s relatively light, which, in my book, makes it absolutely necessary to exercise caution when carrying with a round chambered. There is no trigger safety, so it is imperative that you are unerringly careful.
While it may not seem like a huge upgrade, the manual thumb safety makes the P365 one of the safest everyday carry guns on the market today. The safety itself is ambidextrous and clicks positively into position. A great feature of this model is that it can be loaded and unloaded with the safety on. The same can’t be said for many other guns which only allow loading with the thumb safety off.
15 round magazines do add a bit of length, however they are great for a backup mag. (Josh Wayner for TTAG)
Aside from the safety, the features of the gun are the same as the standard P365 (see our review here). Night sights are standard. They’re easy to use and are very easy to pick up in low light or total darkness. Magazines drop free with no hangups. Included with the gun are two, 10-round mags, one with a short finger extension and the other a flush fit version. Twelve and 15-round extended mags are available, too.
I tested this new SIG P365 version with the safety with a mountain of ammunition to fully ensure that it’s able to pass my own standards for a carry gun and to dispel lingering rumors of problems with the design.
The P365 I received saw over 2,000 rounds right out of the box and was never cleaned or even wiped down. I fired just about every brand of ammo and recorded my results below.
Accuracy shown is the average of three, five-shot groups at 15 yards and velocity is the average of 10 rounds fired over an Oehler 35P chronograph five feet from the muzzle.
As far as general performance was concerned, the P365 shot anything and everything I put through it. I had absolutely no failures to feed, to fire, or to eject with any ammo tested. The pistol was very accurate, especially for a compact carry gun, with virtually everything I fired through it.
Black Hills 100gr +P is an amazing load. (Josh Wayner for TTAG)
Of particular note was the accuracy I got from the Black Hills 100gr HoneyBadger. I have tested this load in numerous guns across many months and even did a standalone review here on TTAG. I keep coming back to this load in my article notes as it is just so damn accurate and reliable. I love all the ammo I test, but for whatever reason this load from Black Hills is always the most accurate at every range.
Close in at 15 yards it was matched by Lehigh Defense’s HERO load, but out to 25 yards it quickly outpaces all the others and behaves like a little rifle round. I was easily able to make hit after hit at 50 yards on a 10” plate using the Black Hills load.
Josh Wayner for TTAG
That said, I am always impressed by the ammo innovations from the other companies featured in this article. For general carry, SIG’s 365 load is hard to beat. You can read the review of that here.
Hornady makes some of the best carry ammo out there and their Critical Duty loads inspire plenty of confidence. Look forward to a detailed review of the 135gr +P this summer. Buffalo Bore makes some of the most powerful 9mm available and you can find a review of the 95gr +P+ here.
Josh Wayner for TTAG
The P365 Manual Safety is one of the most compact, reliable, and accurate handguns you can own today. I will be using this pistol across the summer for most of ammo testing. I think that it will serve me and you well as you read the results I get. I don’t recommend this gun lightly, either.
Caliber: 9x19mm Barrel Length: 3.1” Overall Length: 5.8” Width: 1” Weight: 17.8oz Sights: SIG XRAY Night Sights Magazine: 10 round standard, 12-round magazine and 15-round magazine available MSRP: $599 (seen about $100 lower retail)
Ratings (Out of Five Stars):
Accuracy * * * * * This is probably the most accurate compact semi-automatic everyday carry gun I’ve ever used. It shot like a full-size pistol and refused to miss even small targets.
Reliability * * * * * I put a stupid number of rounds through the P365-MS in only a couple of range trips to ensure it goes bang every time. In 2,000+ rounds it never failed to feed or fire.
Ergonomics * * * * * This is a well-engineered pistol that feels great in the hand and carries easily on the hip. The manual safety lever feels very positive and is easy to disengage.
Customize This * * * * * It already comes with XRAY3 night sights. The ability to change out grip modules, change colors, add lasers, swap sights, and go from 10+1 to as many as 15+1 makes this one of the most user-friendly carry guns out there.
Aesthetics * * * * The gun is small and efficient. I love the smooth lines and high capacity (for a sub-compact). Many small carry guns are plain, if not downright ugly, but SIG managed to make the P365 fairly pretty and functional.
Overall * * * * * Just like the article says, this may be the best carry gun on the market right now. There is really nothing out there that even comes close when you blend size, capacity and features. The addition of the safety option makes it darn close to perfect.
This package will render font awesome icons in your views on the server side. This removes the need to add extra JavaScript or webfont resources on the client side and in doing so reduces the size of your website significantly.
This is achieved by replacing the icons with their svg counterpart before sending the response to the client.
To use Font Awesome icons in your view there are a few new blade directives.
// Let the package discover the best library for this icon.@fa('laravel')// Define the library that should be used.@far('circle') // Regular@fas('circle') // Solid@fab('laravel') // Brands
When using the @fa() directive. The package will scan the different Font Awesome libraries and use the first library where it finds the icon.
The order in which the libraries are scanned is regular, brands, solid. But this can be modified in the configuration.
Middleware
This package includes a middleware that injects a minimal stylesheet into your views on render. By default, this middleware is added to the web middleware group.
If you don’t want to have the style injected automatically, you can disable middleware.all_requests in the configuration. In this case, you will have to add the middleware to selected routes yourself or add your own CSS.
The middleware you should use is \Jerodev\LaraFontAwesome\Middleware\InjectStyleSheet::class.
Configuration
The package contains a few configuration options that can be modified by first publishing the config file using the command below. This will create a fontawesome.php file in your config folder.
The icon libraries that will be available. This is also the order in which the libraries will be searched for icons.
middelware.all_requests
boolean
true
When enabled, the stylesheet needed for the icons will automatically be injected on every request returning html.
To Do
Currently the package only supports basic icon rendering. There is no support for special cases, such as: stacking icons or masking icons, because I never used these myself.
In the future however, I want to add these as well to make this package support the full api that is available using the Font Awesome library.
In a perfect world, there wouldn’t be any errors or bugs in production applications. However, we don’t live in a perfect world, and from experience, you know there is no such thing as a bug-free application. If you are using the Laravel framework, you can leverage its log tracking and error logging to catch bugs early and enhance the performance of your Laravel-based application.
Laravel comes pre-packaged with tools to help you track and monitor events. This reduces the effort required to track down those bugs. It comes with a stackable logging system built on top of the popular Monolog library. It also allows you to set up multiple channels based on the severity of the log or event. These channels include stack (stacked), single, daily, Slack, syslog, monolog, SolarWinds® Papertrail®, and so on.
Single Server Environment
Configuring logging for a single server production environment is simple and straightforward. Since the data is always retained on the server, we do not have to worry about keeping the logs offsite. Laravel handles the log rotation, so you do not have to manually maintain that information either. The following configuration logs debug level errors and exceptions to a log file.
Production environments are dynamic and they often scale up and down, which means that the servers will be created or destroyed with increases and decreases in user traffic or load. This means you cannot rely on file-based logging because storage is ephemeral and load balancers make it quite difficult to track down which web server received a request. In order to aggregate and save the logs for any retention period, you’ll have to set up a dedicated syslog server or use a service like Papertrail, which can store logs and make them accessible in a web browser.
A screenshot of logs in Papertrail.
While setting up a logs server is easy, it’s not beneficial for everyone. A decent amount of Linux knowledge and a dedicated server is required, especially if you’re managing more than one production environment.
I like Papertrail for its ease of setup and use. You just have to set up the logging channel to “papertrail” and add two configurations into your environment file (.env).
You should be able to get the values for these settings in your Papertrail account. There is also documentation on the Laravel site about configuring the Papertrail channel.
Once set up you can easily monitor and search your logs.
Common Errors
5XX Server Errors
These are usually server side or hard errors which are thrown on the server side. These errors usually mean something unexpected happened and your program didn’t know how to handle the situation. The error could be caused by many things and we’ll describe a few common ones below.
Code Syntax Errors
These errors are easy to detect if you have debug turned on or if you’re looking at the error log. Errors usually start with syntax error, unexpected… and will give you the name of the file and line number of the code that caused the error.
PHP version Compatibility
PHP 5.6 and 7.0 hit EOL (end of life) last year and chances are your server isn’t using those versions or won’t be for much longer. I’ve listed a few tools below which you can use to check your code for compatibility.
These errors usually happen when you’re running the PHP outside of Apache/Nginx as a separate process (for example, FPM or CGI) and the response isn’t returned to your web server in a timely manner. Performance tracking middleware defined in the Performance issues section later in the article might be helpful for you for tracking these issues.
Database Connection Issues
This can be solved by checking the credentials for DB connection in your environment file and making sure that the credentials are correct, the application communicates with the database server, and the database/tables exist.
The following are a few log messages thrown by this issue:
SQLSTATE[HY000] [1045] Access denied for user [USERNAME] SQLSTATE[HY000] [2002] Operation timed out
4XX Client Errors
These errors are considered soft errors and are usually thrown when we receive an invalid request from a client.
404 Page Not Found
This error usually means that Laravel was not able to find the controller, controller method or a 404 error was thrown by your custom code. Some common steps to debug these would be to confirm that the route, controller, and method exist. If they all exist, then check to see if your code is throwing a 404 error.
Some common 404 errors are as follows:
Error Message
Possible Reason(s)
404 | Not Found
1. Route is not defined 2. No results were found when findOrFail() was called for a model
Class [CLASS_NAME] does not exist
Controller class does not exist or the path to it is incorrect
Method [METHOD_NAME] does not exist
Method does not exist or the path to it is incorrect
Note: findOrFail() callback on a model returns a 404 error if no matching result is found in the database.
419 Page Expired
Laravel comes pre-loaded with a CSRF protection and it requires you to pass that token with all your non-GET requests. This requires a valid session to be maintained on the server side.
If you wish to exclude any requests from CSRF verification, then add those requests to your VerifyCsrfToken middleware.
/** * The URIs that should be excluded from CSRF verification. * * @var array */ protected $except = [ 'foo/bar', 'foo/*', 'http://example.com/foo/bar', 'http://example.com/foo/*', ];
422 Unprocessable Entity
This error usually means that the data you posted using AJAX was invalid for this request. This happens when you have a Request Rules setup. Laravel validates each request before it passes onto your controller method. The issue may be in your data or the request rule used for the request.
When an AJAX request is made JSON content type request it will return an error message like following, explaining what the issue is.
{ "message": "The given data was invalid.", "errors": { "name": ["The name field is required."], "email": ["The email field is required."] } }
Out of Memory Error
Memory limits on PHP applications exist for a reason. You do not want to allow your application an unlimited amount of memory. This error message exists for that very reason. If you’re receiving an out of memory error it means that there is a memory leak in your application. Maybe you forgot to reset an object, and the size continues to increase until the application doesn’t have any memory left to run.
Allowed memory size of [SIZE] bytes exhausted (tried to allocate [SIZE] bytes)
The following loop will keep running until the program runs out of memory:
A single slow query can slow down your entire application. You did everything you could think of and made sure that all of your queries were using indexes and didn’t do anything; however, maybe you still missed something… How do you monitor for that? It’s simple enough in Laravel. Add the following code to your AppServiceProvider::boot() method:
public function boot() { \DB::listen(function($sql) { if($sql->time > 1000){ \Log::info(“SLOW QUERY DETECTED:”); \Log::info($sql->sql); \Log::info($sql->bindings); \Log::info($sql->time); } }); }
This will log every query that takes longer than a second (1000 ms) to execute. You can adjust the time accordingly to fit your needs. Running an explain on your query will provide you with some insights as to why your query is running slow.
Slow Response Time
Tracking slow response time in Laravel is relatively simple. You can define a middleware like the following example and include it in your requests.
<?php //File Name: app/Middlewares/Performance.php namespace App\Http\Middleware; use Closure; class Performance { public function handle($request, Closure $next) { return $next($request); } public function terminate($request, $response) { $execution_time = microtime(true) - LARAVEL_START; if($execution_time > 1){ // You can change the 1 to a desired amount in seconds \Log::info("Slow Response[{$execution_time}]: You should log some information here."); } } }
After creating the middleware do not forget to include it in your Kernel.php like this:
You can also include it in your web or API route groups if you want to include it in all requests on web/API.
Caching
Caching your content is another way to optimize your application. You don’t have to fetch data from your database if it doesn’t change often. Laravel provides drivers for file, db, memcache, and redis backends. By default, Laravel uses a file-based caching system. Configuring caching in Laravel is easy and can be done in minutes.
Recap
In this article, you learned how we can use logging to reduce the time and effort spent on debugging your code while improving the performance of your application at the same time.
As you see, you can use logging to reduce the time and effort spent debugging your code while improving the performance of your application at the same time.
Data is your friend and it’s there waiting for you to make use of it! Tools like SolarWinds® Papertrail® make it easier to access logs and debug problems. Check out the Papertrail free trial.